📄 system.inc
字号:
; Copyright (C) 1999-2002 Konstantin Boldyshev <konst@linuxassembly.org>;; $Id: system.inc,v 1.18 2002/03/02 20:23:14 konst Exp $;; file : system.inc; created : 08-Apr-1999; modified : 02-Mar-2002; version : 0.16; assembler : nasm 0.98; description : framework and generic stuff (macros, sections, etc); author : Konstantin Boldyshev <konst@linuxassembly.org>; comment : main include file;;0.01: 05-Jun-1999 initial release;0.02: 17-Jun-1999 total rewrite, new macros & syscalls.;0.03: 01-Jul-1999 fixed bugs in __setreg32, __syscall_setregs rewritten,; new syscalls and constants, added optimization for; size/speed;0.04: 01-Aug-1999 fixed more bugs in __setreg32 :), all constants moved; to defines.inc, all syscalls moved to syscall.inc;0.05: 18-Sep-1999 support for elf.inc, I_STRUC and I_END macros;0.06: 03-Jan-2000 _mov, _add, _sub, _cmp; invoke, PROC, ENDP;0.07: 07-Feb-2000 _push, configuration moved to makefile;0.08: 28-Feb-2000 added stack convertion routine, libc support,; various bugfixes (_mov and co);0.09: 14-Mar-2000 jmps, syscall gates;0.10: 21-Aug-2000 started stub for BeOS, _mov improved,; NetBSD and OpenBSD stuff;0.11: 24-Oct-2000 AtheOS stuff;0.12: 19-Jan-2001 _xchg (PR), _jmp (KB);0.13: 21-Feb-2001 modified __syscall_gate (KB);0.14: 11-Feb-2001 added B_STRUC macro (aka ELF_BSTRUC from elf.inc) (BR),; moved __syscall_gate to os_xxx.inc files (KB);0.15: 24-Sep-2001 fixed LIBC stuff, added __LONG_JUMPS__ (KB);0.16: 15-Feb-2002 added SOLARIS, UNIXWARE, improved BeOS stub,; rewritten libc port, _push with 2 args,; added _end label to END macro (KB)%ifndef __SYSTEM_INC%define __SYSTEM_INC;--------------------------------------------------------------------------; default configuration parameters (if not specified at compile time);--------------------------------------------------------------------------;;Operating System;%ifndef __LINUX__%ifndef __ATHEOS__%ifndef __QNXRTP__%define __LONG_JUMPS__%ifndef __BEOS__%ifndef __SOLARIS__%ifndef __UNIXWARE__%define __BSD__%ifndef __FREEBSD__%ifndef __NETBSD__%ifndef __OPENBSD__%error "Invalid OS"%endif%endif%endif%endif%endif%endif%endif%endif%endif;;kernel version;%ifndef __KERNEL__%assign __KERNEL__ 10%endif;;executable format;%ifndef __ELF__%ifndef __AOUT__%error "Invalid executable format"%endif%endif;;optimization method (size/speed);%assign __O_SIZE__ 0%assign __O_SPEED__ 1%ifndef __OPTIMIZE__%assign __OPTIMIZE__ __O_SIZE__ ;size/speed%endif%if __OPTIMIZE__=__O_SPEED__%define __LONG_JUMPS__%endif;;syscall convention;%assign __S_KERNEL__ 0%assign __S_LIBC__ 1%ifndef __SYSCALL__%assign __SYSCALL__ __S_KERNEL__%endif%if __SYSCALL__=__S_LIBC__%define __LONG_JUMPS__%endif;--------------------------------------------------------------------------; include them all;--------------------------------------------------------------------------%include "includes.inc"%ifdef __LINUX__%include "os_linux.inc"%elifdef __FREEBSD__%include "os_freebsd.inc"%elifdef __NETBSD__%include "os_netbsd.inc"%elifdef __OPENBSD__%include "os_openbsd.inc"%elifdef __BEOS__%include "os_beos.inc"%elifdef __ATHEOS__%include "os_atheos.inc"%elifdef __SOLARIS__%include "os_solaris.inc"%elifdef __UNIXWARE__%include "os_unixware.inc"%endif%include "syscall.inc"%ifdef __ELF_MACROS__%include "elf.inc"%endif;--------------------------------------------------------------------------; section macros;--------------------------------------------------------------------------%ifdef __STARTUP__%define START _start_asm%else%define START _start%endif%macro CODESEG 0%ifdef __ELF_MACROS__BEGIN_ELF%else%ifdef __AOUT__ section .text%else %if __OPTIMIZE__=__O_SPEED__ section .text align=16 %elif __OPTIMIZE__=__O_SIZE__ section .text align=1 %endif%endif ;__AOUT__ global START%endif ;__ELF_MACROS__%ifdef STAMP_VERSION db __n__ver db STAMP_VERSION, EOL%endif%ifdef STAMP_DATE db __t__date db STAMP_DATE, EOL, __n%endif;; syscall gate, if any;SYSCALL_GATE%ifdef __STARTUP__;Startup plugin should prepare the stack;in a [ argc | argv[0]... | envp[0].. ] way.%if __SYSCALL__=__S_LIBC__;C style stack: main(argc,**argv,**envp)%assign __S 4 global mainmain: mov ebp,esp xor edx,edx push edx.__env: push edx xor ecx,ecx mov eax,[ebp + __S + 8] or eax,eax jz .__argv.__find_env: cmp [eax],edx jz .__push_env inc ecx add eax,byte 4 jmp short .__find_env.__push_env: sub eax,byte 4 push dword [eax] loop .__push_env .__argv: push edx xor ecx,ecx mov eax,[ebp + __S + 4] or eax,eax jz .__argc.__find_arg: cmp [eax],edx jz .__push_arg inc ecx add eax,byte 4 jmp short .__find_arg.__push_arg: sub eax,byte 4 push dword [eax] loop .__push_arg.__argc: mov eax,[ebp + __S] push eax xor eax,eax xor ecx,ecx xor ebp,ebp jmp START%elifdef __BEOS__ global _start_start:;;convert BeOS startup stack to common ELF stack; pop ebx pop ebx pop esi mov esi,[esi] mov edi,esi mov ecx,ebx.__next1: lodsb or al,al jnz .__next1 dec ecx jnz .__check_end mov ebp,esi.__check_end: cmp [esi],byte 0 jnz .__next1 push byte 0 ;ending NULL dec esi dec esi std.__next2: cmp esi,edi jz .__finish2 lodsb or al,al jnz .__next2.__finish2: inc esi cmp esi,ebp jz .__push_arg push byte 0 ;push NULL before args.__push_arg: push esi ;push argv or envp.__d2: dec esi cmp esi,edi jnz .__next2.__done: push ebx ;push argc cld xor eax,eax xor ebx,ebx xor ecx,ecx xor esi,esi xor edi,edi xor ebp,ebp jmp START%endif%endif ;__STARTUP__%endmacro%macro UDATASEG 0%ifdef __ELF_MACROS__ELF_DATA%else%if __OPTIMIZE__=__O_SPEED__ section .bss align=32%elif __OPTIMIZE__=__O_SIZE__ section .bss%endif%endif%endmacro%macro DATASEG 0%ifndef __ELF_MACROS__%ifdef __AOUT__ section .data%else%if __OPTIMIZE__=__O_SPEED__ section .data align=16%elif __OPTIMIZE__=__O_SIZE__ section .data align=1%endif%endif%endif%endmacro%macro END 0%ifdef __ELF_MACROS__END_ELF%endif_end: ;ld may put this label too%endmacro%macro I_STRUC 1%ifdef __ELF_MACROS__ELF_ISTRUC %1%elseistruc %1%endif%endmacro%macro I_END 0%ifdef __ELF_MACROS__ELF_IEND%elseiend%endif%endmacro; (BR); B_STRUC is a more succinct method for using a Nasm structure; definition within a DATA section. The first argument names a; previously defined structure. The following arguments indicate; the members of that structure to declare here.;; Please note that the fields of the structure must have been defined; as local labels (i.e., with a dot prefix).%ifdef __ELF_MACROS__%define B_STRUC ELF_BSTRUC%else%macro B_STRUC 1-*%push foo%define %$strucname %1%%top_%$strucname:%rep %0 - 1%rotate 1resb %{$strucname}%1 - ($ - %%top_%$strucname)%1:%endrepresb %{$strucname}_size - ($ - %%top_%$strucname)%pop%endmacro%endif;------------------------------------------------------------------; general purpose optimizing macros;------------------------------------------------------------------;;explicit short jump;%define jmps jmp short;;auto short/long jump (I hate nasm);currently works only backwards :(;do not use;%macro _jmp 1%%__offset_%1 equ $-%1%assign __offset__ %%__offset_%1%if (__offset__<0) && (__offset__>0xFFFFFF80) jmp short %1%elif (__offset__>0) && (__offset__<0x80) jmp short %1%else jmp %1%endif%endmacro;;intellectual register assignment, generates smaller code.. long weird macro.;warning: macro may touch flags!;%macro _mov 2-3%ifnidn %2,EMPTY %if __OPTIMIZE__=__O_SPEED__ %ifid %2 mov %1,%2 %elifnum %2 %if %2=0 sub %1,%1 %else mov %1,%2 %endif %else mov %1,%2 %endif %else ;%if __OPTIMIZE__=__O_SIZE__ %ifid %2 %ifnidni %1,%2 mov %1,%2 %endif %elifstr %2 mov %1,%2 %elifnum %2 %if %2=0 xor %1,%1 %elif %2<0 && %2>0xffffff7f push byte %2 pop %1 %elif %2<0 mov %1,%2 %elif %2<0x80 push byte %2 pop %1 %elif %2<0x100 %ifidn %1,eax __setreg32_08_lo al,%1,%2 %elifidn %1,ebx __setreg32_08_lo bl,%1,%2 %elifidn %1,ecx __setreg32_08_lo cl,%1,%2 %elifidn %1,edx __setreg32_08_lo dl,%1,%2 %else mov %1,%2 %endif %elif %2<0x00010000 %if (%2 % 0x100) = 0 %ifidn %1,eax __setreg32_08_hi ah,%1,%2 %elifidn %1,ebx __setreg32_08_hi bh,%1,%2 %elifidn %1,ecx __setreg32_08_hi ch,%1,%2 %elifidn %1,edx __setreg32_08_hi dh,%1,%2 %else mov %1,%2 %endif %else %ifidn %1,eax __setreg32_16 ax,%1,%2 %elifidn %1,ebx __setreg32_16 bx,%1,%2 %elifidn %1,ecx __setreg32_16 cx,%1,%2 %elifidn %1,edx __setreg32_16 dx,%1,%2 %else mov %1,%2 %endif %endif %else mov %1,%2 %endif %else mov %1,%2 %endif %endif%endif%endmacro;; _mov helpers;%macro __setreg32_08_lo 3%ifnidn %3,EMPTY xor %2,%2 mov %1,%3%endif%endmacro%macro __setreg32_08_hi 3%ifnidn %3,EMPTY xor %2,%2 mov %1,(%3 / 0x100)%endif%endmacro%macro __setreg32_16 3%ifnidn %3,EMPTY %if %3=0xFFFF xor %2,%2 dec %1 %else mov %2,%3 %endif%endif%endmacro;; another weird one :);%macro _add 2%if %2 != 0 %if __OPTIMIZE__=__O_SPEED__ add %1,%2 %else ;%if __OPTIMIZE__=__O_SIZE__ %if %2=1 inc %1 %elif %2=2 inc %1 inc %1 %elif %2=0xFFFFFFFF || %2=-1 dec %1 %elif %2=0xFFFFFFFE || %2=-2 dec %1 dec %1 %elif %2=0x80 add %1,byte 0x7F inc %1 %elif %2>0 && %2<0x80 add %1,byte %2 %elif %2<0 && %2>-0x80 sub %1, byte -(%2) %else add %1,%2 %endif %endif%endif%endmacro;;;%macro _sub 2%if %2 != 0 %if __OPTIMIZE__=__O_SPEED__ sub %1,%2 %else ;%if __OPTIMIZE__=__O_SIZE__ %if %2=1 dec %1 %elif %2=2 dec %1 dec %1 %elif %2=0x80 sub %1,byte 0x7F dec %1 %elif %2>0 && %2<0x80 sub %1,byte %2 %elif %2=-2 || %2=0xfffffffe inc %1 inc %1 %elif %2=-1 || %2=0xffffffff inc %1 %elif %2>-0x80 && %2<0 add %1, byte -(%2) %else sub %1,%2 %endif %endif%endif%endmacro%macro _cmp 2%ifid %2 cmp %1,%2%elif %2=0 or %1,%1%elif (%2>0 && %2<0x80) || (%2<0 && %2>-0x80) cmp %1,byte %2%else cmp %1,%2%endif%endmacro%macro _and 2%ifid %2 and %1,%2%elif %2=0 xor %1,%1%elif (%2>0 && %2<0x80) || (%2<0 && %2>-0x80) and %1,byte %2%else and %1,%2%endif%endmacro%macro _or 2%ifid %2 or %1,%2%elif (%2>0 && %2<0x80) || (%2<0 && %2>-0x80) or %1,byte %2%else or %1,%2%endif%endmacro%macro _xor 2%ifid %2 xor %1,%2%elif (%2>0 && %2<0x80) || (%2<0 && %2>-0x80) xor %1,byte %2%else xor %1,%2%endif%endmacro%macro _push 1-2%ifidn %1,EMPTY %if %0>1 push %2 %endif%elifid %1 push dword %1%elifstr %1 push dword %1%elifnum %1 %if %1=0 || (%1>0 && %1<0x80) || (%1<0 && %1>-0x80) push byte %1 %else push dword %1 %endif%else push dword %1%endif%endmacro;PR: <xchg> is very slow, reg/mem takes 33 clocks.;this macro for nasm helps speeding up regardless of what addressing mode used%macro _xchg 2%if __OPTIMIZE__=__O_SPEED__%assign ea 4%else%assign ea 0%ifid %{2}%assign ea ea|2%endif%ifid %{1}%assign ea ea|1%endif%endif;handles reg,mem and mem,reg differently, because:; 9 clocks if last, negated opd is in memory; 5 clocks if that one is a register%if ea=2 add %{1},%{2} sub %{2},%{1} add %{1},%{2} neg dword %{2}%elif ea=1 add %{2},%{1} sub %{1},%{2} add %{2},%{1} neg dword %{1}%else; 2 clocks w. reg,reg; (lea variant wasn't faster, may be cpu dependent?); 33 clocks w. reg,mem or mem,reg - either case xchg %{1},%{3}%endif%endmacro;;former macros.inc;%macro invoke 2-10%assign _params %0%assign _params _params-1%if %0 > 9 push dword %10%endif%if %0 > 8 push dword %9%endif%if %0 > 7 push dword %8%endif%if %0 > 6 push dword %7%endif%if %0 > 5 push dword %6%endif%if %0 > 4 push dword %5%endif%if %0 > 3 push dword %4%endif%if %0 > 2 push dword %3%endif push dword %2 call %1%assign _params _params*4 _add esp,_params%endmacro%macro PROC 1-10GLOBAL %{1}%{1}:%if %0 > 1%define %2 dword[ebp+8]%endif%if %0 > 2%define %3 dword[ebp+12]%endif%if %0 > 3%define %4 dword[ebp+16]%endif%if %0 > 4%define %5 dword[ebp+20]%endif%if %0 > 5%define %6 dword[ebp+24]%endif%if %0 > 6%define %7 dword[ebp+28]%endif%if %0 > 7%define %8 dword[ebp+32]%endif%if %0 > 8%define %9 dword[ebp+36]%endif%if %0 > 9%define %10 dword[ebp+40]%endif push ebp mov ebp,esp%endmacro%macro ENDP 0 pop ebp ret%endmacro%endif ;__SYSTEM_INC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -