アセンブリ-マクロ

マクロの記述は、アセンブリ言語でのモジュラープログラミングを保証するもう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!