这篇文章上次修改于 663 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
Function Definition & Call
This part is simple. Use following template to define a new function.
<function-name> PROC
; function body
ret
<function-name> ENDPE.g.:
add_2_to_ax PROC
add ax, 2
ret
add_2_to_ax ENDPAnd 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
endpLike 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,...]
ENDMUnlike 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
retLabel 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 3This 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 3This 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.
没有评论