正如标题所述,为什么人们会使用"movl $ 1,%eax"而不是"movb $ 1,%eax",我被告知movl会将%eax的高阶位清零,但不是%eax一个相当于系统字大小的寄存器?意思是movl实际上是一个整数运算(而不是长整数?)
我显然对这一切感到困惑; 谢谢.
Jas*_*son 41
反对,比如说,"movb $ 1,%eax"
该指令无效.你不能在movb指令中使用eax.您将改为使用8位寄存器.例如:
movb $ 1,$ al
但是不是%eax是一个相当于系统字大小的寄存器吗?
不管系统的寄存器大小如何,EAX始终为32位值.
您将C变量大小与寄存器大小混淆.C变量大小可能会根据您的系统和编译器而改变.
汇编比C简单.在GAS汇编中,指令后缀有字母"b","s","w","l","q"或"t",以确定操作的操作数大小.
* b = byte (8 bit)
* s = short (16 bit integer) or single (32-bit floating point)
* w = word (16 bit)
* l = long (32 bit integer or 64-bit floating point)
* q = quad (64 bit)
* t = ten bytes (80-bit floating point)
Run Code Online (Sandbox Code Playgroud)
这些尺寸是不变的.它们永远不会改变.al始终为8位,eax始终为32位.
在32位机器上,%eax是一个4字节(32位)寄存器.movl将写入所有4个字节.在您的示例中,它会将高3字节清零,并将1放在最低字节中.movb只会改变低位字节.
%eax是一个32位寄存器.要使用较小的宽度,您需要%ax16位.%ax可以进一步分为%ah高字节%ax和%al低字节.其他x86 GPR也是如此.
查看指令的英特尔指令集参考mov,我没有看到可以将单个字节移动到32位寄存器的变体 - 它可能被解释为移入%al.
由于movl是32位指令,因此在立即值的情况下,高位字节的值将对应于零.如果你从内存移动,你将移动整个32位字.
%eax除非你movl $0, %eax或者如果你,否则不会归零xorl %eax, %eax.否则它会保留之前的任何值.当你movl $1, %eax,你将最终0x00000001进入寄存器,因为32位指令将32位立即值移入寄存器.
long最初是 32 位,而int和short是 16 位。每次有人推出新操作系统时,操作码的名称都不会改变。