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.

image.png

Here we recommend that always use LOCAL when you need to use flag inside a macro function.