有人可以解释x86汇编中宏和程序/方法之间的区别吗?我完全迷失了。谢谢。
答案 0 :(得分:1)
宏在最终编译步骤之前进行内联扩展,而程序将通过'call'和'ret'操作在最终的可执行文件中实现。
基本上,宏是语法糖,可以使您的源代码更漂亮或允许您更快地输入它。要使用以下链接中的宏示例(逐字复制):
; 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
这相当于:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, len1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, len2
int 80h
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, len3
int 80h
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
您可以看到使用宏的前一代码更简洁,更容易阅读。在编译器扩展对宏的每个引用之后,第二种形式将基本上是最终编译的。
程序不会以这种方式重复,它们被编译一次,'call'操作码用于输入程序,'ret'操作码用于保留程序。
将非重要函数实现为过程可能会导致可执行文件小得多,因为每次调用都不会复制代码。但是,使用过程意味着您必须处理通过寄存器传递任何所需参数,并且'call'和'ret'本身具有非零执行时间。因此,如果函数足够大并且在代码中的足够位置调用,它可以成为大小与性能的权衡。
https://www.tutorialspoint.com/assembly_programming/assembly_macros.htm
https://www.tutorialspoint.com/assembly_programming/assembly_procedures.htm