アセンブリ-マクロ
マクロの記述は、アセンブリ言語でのモジュラープログラミングを保証するもう1つの方法です。
マクロは一連の命令であり、名前で割り当てられ、プログラムのどこでも使用できます。
NASMでは、マクロは次のように定義されます。 %macro そして %endmacro ディレクティブ。
マクロは%macroディレクティブで始まり、%endmacroディレクティブで終わります。
マクロ定義の構文-
%macro macro_name number_of_params
<macro body>
%endmacro
ここで、number_of_paramsは数値パラメーターを指定し、macro_nameはマクロの名前を指定します。
マクロは、マクロ名と必要なパラメーターを使用して呼び出されます。プログラムで命令のシーケンスを何度も使用する必要がある場合は、それらの命令をマクロに入れて、常に命令を書き込む代わりに使用できます。
たとえば、プログラムの非常に一般的な必要性は、画面に文字列を書き込むことです。文字列を表示するには、次の一連の命令が必要です-
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
上記の文字列の表示例では、レジスタEAX、EBX、ECX、およびEDXがINT80H関数呼び出しによって使用されています。したがって、画面に表示する必要があるたびに、これらのレジスタをスタックに保存し、INT 80Hを呼び出してから、スタックからレジスタの元の値を復元する必要があります。したがって、データの保存と復元のために2つのマクロを作成すると便利な場合があります。
IMUL、IDIV、INTなどの一部の命令では、特定のレジスタに情報を格納する必要があり、特定のレジスタに値を返す必要があることも確認しています。プログラムがすでにこれらのレジスタを使用して重要なデータを保持している場合は、これらのレジスタの既存のデータをスタックに保存し、命令の実行後に復元する必要があります。
例
次の例は、マクロの定義と使用を示しています-
; 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
上記のコードをコンパイルして実行すると、次の結果が得られます。
Hello, programmers!
Welcome to the world of,
Linux assembly programming!