位置:首页 > > Assembly 宏

Assembly 宏

编写宏是确保在汇编语言模块化编程的另一种方式。

  • 宏是一个指令序列,通过名称和分配程序可以在任何地方使用。

  • 在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

我们已经观察到,一些指令IMUL一样,IDIV,INT等,需要的一些信息被储存在一些特定的寄存器,甚至在一些特定的寄存器(次)返回值。如果该程序已经在使用这些寄存器用于保存重要数据,然后从这些寄存器中的现有数据应保存在堆栈的指令被执行后,恢复。

在上述示例中,还显示字符串,寄存器EAX,EBX ECX和EDX,我们将使用INT 80H函数调用。所以,每次在屏幕上显示,需要这些寄存器保存在栈中调用INT 80H,然后恢复从堆栈中的寄存器的原始值。因此,它可能是有用的写两个宏用于保存和恢复数据。

例子:

下面的例子显示了定义和使用宏:

; 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 yiibai
	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!