Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mammon's NASM macro's

99 views
Skip to first unread message

Rod Pemberton

unread,
Nov 26, 2007, 8:56:14 AM11/26/07
to
Mammon's macros.asm for NASM.
Macro's for most C style flow control.
These were once available from here (now dead):
http://www.eccentrica.org/Mammon/macros.asm

File starts with "High-Level Call" line after my signature.


Rod Pemberton


;----------High-Level Call
;Usage:
; ccall FuncName, param1, param2, param 3...
; pcall FuncName, param1, param2, param 3...
; stdcall FuncName, param1, param2, param 3...
; fastcall FuncName, param1, param2, param 3...
%macro pcall 2-9 ;Pascal Call: push first value first, no cleanup
%define _j %1
%rep %0-1
%rotate 1
push %1
%endrep
call _j
%endmacro

%macro ccall 2-9 ;C Call: push last value first, cleanup
%define _j %1
%assign __params %0-1
%rep %0-1
%rotate -1
push %1
%endrep
call _j
%assign __params __params * 4
add esp, __params
%endmacro

%macro stdcall 2-9 ;Windows StdCall: push last value first, no cleanup
%define _j %1
%rep %0-1
%rotate -1
push %1
%endrep
call _j
%endmacro

%macro fastcall 2-9 ;Borland FastCall: use registers, no cleanup
%define _j %1
%assign __pnum 1
%rep %0-4
%rotate -1
%if __pnum = 1
mov eax, %1
%elif __pnum = 2
mov edx, %1
%elif __pnum = 3
mov ebx, %1
%else
push %1
%endif
%assign __pnum __pnum+1
%endrep
call _j
%endmacro

;----------IF-THEN-ELSE Loops
;Usage:
; IF Value, Cond, Value
; ;if code here
; ELSIF Value, Cond, Value
; ;else-if code here
; ELSE
; ;else code here
; ENDIF
;Where Value is a variable, register, or integer -- but not EAX or EBX!!
;Where Cond is the conditional -- a, ae, b, be, e, g, ge, le, ne, nz, z,
etc..
%macro IF 3
%push if
%assign __curr 1
; %if %1 != eax
mov eax, %1
; %endif
; %if %3 != ebx
mov ebx, %3
; %endif
cmp eax, ebx
j%+2 %%if_code
jmp %$loc(__curr)
%%if_code:
%endmacro

%macro ELSIF 3
%ifctx if
jmp %$end_if
%$loc(__curr):
%assign __curr __curr+1
; %if %1 != eax
mov eax, %1
; %endif
; %if %3 != ebx
mov ebx, %3
; %endif
cmp eax, ebx
j%+2 %%elsif_code
jmp %$loc(__curr)
%%elsif_code:
%else
%error "'ELSIF' can only be used following 'IF'"
%endif
%endmacro

%macro ELSE 0
%ifctx if
jmp %$end_if
%$loc(__curr):
%assign __curr __curr+1
%else
%error "'ELSE' can only be used following an 'IF'"
%endif
%endmacro

%macro ENDIF 0
%$loc(__curr):
%$end_if:
%pop
%endmacro

;----------SWITCH-CASE Blocks
;Usage:
; SWITCH Variable
; CASE Int
; ;case1 code here
; BREAK
; CASE Int
; ;case2 code here
; BREAK
; DEFAULT
; ;default code here
; BREAK
; ENDSWITCH
;Where Variable is a variable of INT to DWORD value [eax is used to store]
;Where Int is an immediate INT to DWORD value [ebx is used to store]
%macro SWITCH 1
%push switch
%assign __curr 1
mov eax, %1
jmp %$loc(__curr)
%endmacro

%macro CASE 1
%ifctx switch
%$loc(__curr):
%assign __curr __curr+1
mov ebx, %1
cmp eax, ebx
jne %$loc(__curr)
%else
%error "'CASE' can only be used in a 'SWITCH' block"
%endif
%endmacro

%macro DEFAULT 0
%ifctx switch
%$loc(__curr):
%else
%error "'DEFAULT' can only be used in a 'SWITCH' block"
%endif
%endmacro

%macro BREAK 0
jmp %$endswitch
%endmacro

%macro ENDSWITCH 0
%ifctx switch
%$endswitch:
%pop
%else
%error "'ENDSWITCH' can only be used in an 'SWITCH' block"
%endif
%endmacro

;----------DO-FOR and DO-WHILE Loops
;Usage:
; DO
; ;code to do here
; FOR min, cond, max, step
;Where Min is a value or variable of INT to DWORD value [eax is used]
;Where Cond is condition -- a, ae, b, be, g, ge, l, le, n, ne, z
;Where Max is an INT to DWORD value [ebx is used to store]
;Where Step is an INT to DWORD value to be added to Min at each loop
;e.g. FOR 0, l, 100, 1 == for(x=0; x<100, x++) do code...;
; DO
; ;code to do here
; WHILE variable, condition, value
;Where variable is a value or variable of INT to DWORD value [eax is used]
;Where condition is a conditional -- a, ae, b, be, g, ge, l, le, n, ne, z
;Where Value is an INT to DWORD value [ebx is used to store]
;e.g. WHILE Counter, l, 100 == while( counter < 100 ) do code...;
%macro DO 0
%push do
jmp %$init_loop
%$start_loop:
push eax
%endmacro

%macro FOR 4
%ifctx do
pop eax
add eax, %4
cmp eax, %3
j%-2 %%end_loop
jmp %$start_loop
%$init_loop:
mov eax, %1
jmp %$start_loop
%%end_loop:
%pop
%else
%error "'FOR' must be preceded by a 'DO'"
%endif
%endmacro

%macro WHILE 3
%ifctx do
pop eax
mov ebx, %3
cmp eax, ebx
j%+2 %%end_loop
jmp %$start_loop
%$init_loop:
mov eax, %1
jmp %$start_loop
%%end_loop:
%pop
%else
%error "'WHILE' must be preceded by a 'DO'"
%endif
%endmacro

;----------Procedure Declarations
;Usage:
;PROC ProcName Parameter1, Parameter2, Parameter3...
;LOCALDD Dword_Variable [opt]
;LOCALDW Word_Variable [opt]
;LOCALDB Byte_Variable [opt]
; ;procedure code here
;ENDP
;
;ENTRYPROC
;procedure code here
;ENDP
;
;Note that parameters are set up to EQU to ebp-x
;Note that locals are set up to EQU to ebp+x
;Note that neither LOCALS or Parameters are necessary, as in ENTRYPROC

%macro PROC 1-9
GLOBAL %1
%1:
%assign _i 4
%rep %0-1
%2 equ [ebp-_i]
%assign _i _i+4
%rotate 1
%endrep
push ebp
mov ebp, esp
%push local
%assign __ll 0
%endmacro

%macro ENDP 0
%ifctx local
%pop
%endif
pop ebp
%endmacro

%macro ENTRYPROC 0
PROC main
%endmacro

%macro LOCALVAR 1
sub esp, 4
%1 equ [ebp + __ll]
%endmacro

%macro LOCALDB 1
%assign __ll __ll+1
LOCALVAR %1
%endmacro

%macro LOCALDW 1
%assign __ll __ll+2
LOCALVAR %1
%endmacro

%macro LOCALDD 1
%assign __ll __ll+4
LOCALVAR %1
%endmacro

;----------Data Declarations
;Usage:
;CHAR Name, String
;INT Name, Byte
;WORD Name, Word
;DWORD Name, Dword
;e.g. CHAR UserName, "Joe User"
; INT Timeout, 30
; WORD Logins
; DWORD Password
;Note that not specifying a value causes the variable to default to 0
;Note that strings are automatically zero-terminated
%macro CHAR 1-2 0
%1: DB %2,0
%endmacro

%macro INT 1-2 0
%1: DB %2
%endmacro

%macro WORD 1-2 0
%1: DW %2
%endmacro

%macro DWORD 1-2 0
%1: DD %2
%endmacro


0 new messages