Assembly - Macro
La scrittura di una macro è un altro modo per garantire la programmazione modulare in linguaggio assembly.
Una macro è una sequenza di istruzioni, assegnata da un nome e può essere utilizzata ovunque nel programma.
In NASM, le macro sono definite con %macro e %endmacro direttive.
La macro inizia con la direttiva% macro e termina con la direttiva% endmacro.
La sintassi per la definizione di macro -
%macro macro_name number_of_params
<macro body>
%endmacro
Dove, number_of_params specifica i parametri del numero, macro_name specifica il nome della macro.
La macro viene richiamata utilizzando il nome della macro insieme ai parametri necessari. Quando è necessario utilizzare una sequenza di istruzioni molte volte in un programma, è possibile inserire tali istruzioni in una macro e utilizzarla invece di scrivere le istruzioni tutto il tempo.
Ad esempio, un'esigenza molto comune per i programmi è scrivere una stringa di caratteri sullo schermo. Per visualizzare una stringa di caratteri, è necessaria la seguente sequenza di istruzioni:
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
Nell'esempio precedente di visualizzazione di una stringa di caratteri, i registri EAX, EBX, ECX e EDX sono stati utilizzati dalla chiamata alla funzione INT 80H. Quindi, ogni volta che è necessario visualizzare sullo schermo, è necessario salvare questi registri sullo stack, richiamare INT 80H e quindi ripristinare il valore originale dei registri dallo stack. Quindi, potrebbe essere utile scrivere due macro per salvare e ripristinare i dati.
Abbiamo osservato che alcune istruzioni come IMUL, IDIV, INT, ecc. Richiedono che alcune informazioni siano memorizzate in alcuni registri particolari e che restituiscano anche valori in alcuni registri specifici. Se il programma stava già utilizzando quei registri per conservare dati importanti, i dati esistenti da questi registri dovrebbero essere salvati nello stack e ripristinati dopo l'esecuzione dell'istruzione.
Esempio
L'esempio seguente mostra la definizione e l'utilizzo delle macro:
; 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
Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:
Hello, programmers!
Welcome to the world of,
Linux assembly programming!