Baugruppe - Makros
Das Schreiben eines Makros ist eine weitere Möglichkeit, die modulare Programmierung in Assemblersprache sicherzustellen.
Ein Makro ist eine Folge von Anweisungen, die durch einen Namen zugewiesen werden und an einer beliebigen Stelle im Programm verwendet werden können.
In NASM werden Makros mit definiert %macro und %endmacro Richtlinien.
Das Makro beginnt mit der% -Makro-Direktive und endet mit der% endmacro-Direktive.
Die Syntax für die Makrodefinition -
%macro macro_name number_of_params
<macro body>
%endmacro
Wobei number_of_params die Nummernparameter angibt, macro_name den Namen des Makros angibt.
Das Makro wird aufgerufen, indem der Makroname zusammen mit den erforderlichen Parametern verwendet wird. Wenn Sie eine Folge von Anweisungen in einem Programm mehrmals verwenden müssen, können Sie diese Anweisungen in ein Makro einfügen und verwenden, anstatt die Anweisungen ständig zu schreiben.
Beispielsweise besteht ein sehr häufiger Bedarf an Programmen darin, eine Zeichenfolge auf den Bildschirm zu schreiben. Zum Anzeigen einer Zeichenfolge benötigen Sie die folgende Befehlsfolge:
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
Im obigen Beispiel für die Anzeige einer Zeichenfolge wurden die Register EAX, EBX, ECX und EDX vom Funktionsaufruf INT 80H verwendet. Jedes Mal, wenn Sie auf dem Bildschirm anzeigen müssen, müssen Sie diese Register auf dem Stapel speichern, INT 80H aufrufen und dann den ursprünglichen Wert der Register aus dem Stapel wiederherstellen. Daher kann es nützlich sein, zwei Makros zum Speichern und Wiederherstellen von Daten zu schreiben.
Wir haben festgestellt, dass einige Anweisungen wie IMUL, IDIV, INT usw. einige der Informationen benötigen, um in bestimmten Registern gespeichert zu werden, und sogar Werte in bestimmten Registern zurückgeben müssen. Wenn das Programm diese Register bereits zum Speichern wichtiger Daten verwendet hat, sollten die vorhandenen Daten aus diesen Registern im Stapel gespeichert und nach Ausführung des Befehls wiederhergestellt werden.
Beispiel
Das folgende Beispiel zeigt das Definieren und Verwenden von Makros -
; 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
Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:
Hello, programmers!
Welcome to the world of,
Linux assembly programming!