当我将用EQU定义的常量复制到NASM汇编中的EAX时会发生什么?

时间:2013-09-16 05:33:44

标签: assembly nasm

在遇到Why is my register-constant comparison not working in NASM Assembly?的头痛之后,我发现我一直在将1字节变量(db)复制到EAX,这意味着变量之后的三个字节会被复制同样。现在我知道了,我正在查看类似场景的代码,并发现了这个:

.data中,我有一个数组,其大小定义为常量:

array  db   1,2,3,4
size   equ  $-array

稍后,在.text我有这个:

mov EAX,size

这让我想知道:到底发生了什么? size的大小是多少?这是一个字节吗?一个字? EAX是否应该接收额外的字节?

2 个答案:

答案 0 :(得分:3)

它是an immediate,汇编程序应该为它选择最合适的大小(如果有多个可能的编码)。如果可能的最小尺寸超过目标寄存器的大小,则应该出现错误,或至少发出警告。

在您的示例中,行mov EAX,size会像您键入mov EAX,4一样汇编。

答案 1 :(得分:2)

是从实际位置减去array的开头计算的立即数值。 equ%define之间的重要区别在于编译器直接替换使用$的{​​{1}}符号,而equ只是在预处理代码时有用的文本表示,所以%define对于每次出现都是不同的。使用$的相应代码是

%define

尽管array: db 1, 2, 3, 4 array_end: %define array_end - array 对于数组数据操作似乎是完美的,但equ对于stringss非常有用。

当编译器达到你的指令时到底发生了什么? 它只是将常量的名称替换为已经计算的值。编译器然后按如下方式对指令进行编码:

%define

其他寄存器具有不同的值,可在“英特尔手册”中找到。 mov r32, imm -> 0xB8 + 0x00 (for EAX) size -> 0x04 0x00 0x00 0x00 的加法是英特尔节省1个字节的技巧,用于在0xB8字节中存储REG代码。

指令通常不会使用这种技巧,但是一些频繁的指令通过使用特殊操作码来累加器寄存器来保存一个字节。