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!