This blog was last modified 429 days before.
Function Definition & Call
This part is simple. Use following template to define a new function.
<function-name> PROC
; function body
ret
<function-name> ENDP
E.g.:
add_2_to_ax PROC
add ax, 2
ret
add_2_to_ax ENDP
And you can call this function by using call add_2_to_ax
. Just remember CALL
and RET
.
Passing Parameters
To be short, there is no convenient way to do such thing. Different language, CPU, companys etc may has its own convention. Here we generally use stack to pass parameter.
mov ah, 'A'
mov al, 'B'
mov bp, sp
push ax
call print_two_char
pop ax
ret
print_two_char proc
mov bx, 0b800h
mov ds, bx
mov ax, [bp - 2]
mov [0], ah
mov [2], al
ret
endp
Like the code above, we use the stack to store our parameter.
Macro Function
The template of macro funcion is as below:
<macro_func_name> MACRO [parameters,...]
ENDM
Unlike the normal function, seems macro function are not actually function, so it don't need a CALL
and RET
instruction. Just use it by its name when you need, see example below:
add_ax MACRO delta
add ax, delta
ENDM
mov ax, 1
add_ax 3
ret
Label In Macro Function
Notice that if you need to use label in macro, use LOCAL
mark.
Check example below:
loop_inc_ax macro times
mov cx, times
inc_loop:
inc ax
loop inc_loop
endm
mov ax, 0
loop_inc_ax 2
loop_inc_ax 3
This code is wrong and compiler compliants: (10) duplicate declaration of: INC_LOOP
. This is because we use loop_inc_ax
2 times, so there will actually be 2 inc_loop
marks exists in our code when compile.
To solve this, we should apply some slightly change to our original code and use LOCAL
keyword like below:
loop_inc_ax macro times
local inc_loop
mov cx, times
inc_loop:
inc ax
loop inc_loop
endm
mov ax, 0
loop_inc_ax 2
loop_inc_ax 3
This time the two local mark won't conflict again, you can see from the image below that they now point to different addresses.
Here we recommend that always use LOCAL
when you need to use flag inside a macro function.
No comment