Search code examples
assemblymethodsmacrosx86irvine32

Difference betwee Macros and Procedures/methods in x86 Assembly


Can someone explain the difference between Macros and procedures/methods in x86 Assembly? I am totally lost. Thank you.


Solution

  • Macros are expanded inline before the final compiling step while procedures will be implemented in the final executable with 'call' and 'ret' operations.

    Basically macros are syntactic sugar to make your source code prettier or allow you to enter it faster. To use the macro example from the link below (copied verbatim):

    ; A macro with two parameters
    ; Implements the write system call
       %macro write_string 2 
          mov   eax, 4
          mov   ebx, 1
          mov   ecx, %1
          mov   edx, %2
          int   80h
       %endmacro
    
    section .text
       global _start            ;must be declared for using gcc
    
    _start:                     ;tell linker entry point
       write_string msg1, len1               
       write_string msg2, len2    
       write_string msg3, len3  
    
       mov eax,1                ;system call number (sys_exit)
       int 0x80                 ;call kernel
    
    section .data
    msg1 db 'Hello, programmers!',0xA,0xD   
    len1 equ $ - msg1           
    
    msg2 db 'Welcome to the world of,', 0xA,0xD 
    len2 equ $- msg2 
    
    msg3 db 'Linux assembly programming! '
    len3 equ $- msg3
    

    This would be equivalent to:

    section .text
       global _start            ;must be declared for using gcc
    
    _start:                     ;tell linker entry point
       mov   eax, 4
       mov   ebx, 1
       mov   ecx, msg1
       mov   edx, len1
       int   80h             
       mov   eax, 4
       mov   ebx, 1
       mov   ecx, msg2
       mov   edx, len2
       int   80h    
       mov   eax, 4
       mov   ebx, 1
       mov   ecx, msg3
       mov   edx, len3
       int   80h
       mov eax,1                ;system call number (sys_exit)
       int 0x80                 ;call kernel
    
    section .data
    msg1 db 'Hello, programmers!',0xA,0xD   
    len1 equ $ - msg1           
    
    msg2 db 'Welcome to the world of,', 0xA,0xD 
    len2 equ $- msg2 
    
    msg3 db 'Linux assembly programming! '
    len3 equ $- msg3
    

    You can see that the former code using the macro is more concise and more easily read. The second form will be essentially what is finally compiled, after the compiler expands each reference to the macro.

    Procedures are not duplicated in that manner, they are compiled once and the 'call' opcode is used to enter the procedure and the 'ret' opcode to leave it.

    Implementing non-trivial functions as procedures can result in a much smaller executable, because the code is not replicated for each call. However, using a procedure means you would have to handle passing any required parameters via register, and the 'call' and 'ret' themselves have non-zero execution time. So it can becomes a tradeoff of size vs performance if the function is large enough and called in enough places in the code.

    https://www.tutorialspoint.com/assembly_programming/assembly_macros.htm

    https://www.tutorialspoint.com/assembly_programming/assembly_procedures.htm