为什么会使用"movl $ 1,%eax"而不是"movb $ 1,%eax"

Neg*_*ent 20 x86 assembly

正如标题所述,为什么人们会使用"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位.


Vic*_*der 7

在32位机器上,%eax是一个4字节(32位)寄存器.movl将写入所有4个字节.在您的示例中,它会将高3字节清零,并将1放在最低字节中.movb只会改变低位字节.

  • 是.在IA32架构(通常称为x86)中,"long"表示4个字节,movl表示"移动长". (2认同)

Aar*_*otz 5

%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位立即值移入寄存器.

  • 除非您明确这样做,否则 %eax 永远不会被清零。如果使用 movb 仅写入其中一个字节,则其他字节不变。 (2认同)

Ano*_*on. 4

long最初是 32 位,而intshort是 16 位。每次有人推出新操作系统时,操作码的名称都不会改变。

  • 操作系统的版本与类型的命名约定有什么关系? (2认同)
  • 这就是为什么我更喜欢 Intel 语法而不是 GAS 语法。Intel: mov dword eax, ecx GAS: movl eax, ecx “l”大小的操作数让人困惑。更多人知道“dword”意味着 32 位。 (2认同)