【问题标题】:x86 assembly memory operandsx86 汇编内存操作数
【发布时间】:2010-12-16 18:52:05
【问题描述】:

大家好 我有一个关于 x86 的问题。在英特尔手册中,某些指令可能采用不同类型的内存操作数。 例如。 IDIV r/m8 或 IDIV r/m16 或 IDIV r/m32 或 IDIV r/m64 现在它们都是 IDIV 是否有可能知道操作数是 m8、m16、m32 还是 m64? 我在想如果操作数是 m8 那么它是由一个 8 位寄存器寻址的,例如。 ax if 32 then eax,esp... 我的假设正确吗?如我错了请纠正我 欢迎任何建议 谢谢

【问题讨论】:

    标签: assembly x86 x86-64 cpu-registers operands


    【解决方案1】:

    是的,用作操作数的寄存器解决了歧义。 (但请注意,ax 是一个 16 位寄存器,而不是 8 位寄存器 - 高字节或低字节分别为 ahal。)

    如果您只是指内存操作数,则需要使用BYTE PTRWORD PTRDWORD PTR 说明符来解决歧义,如下所示:

    mov dword ptr [eax], 0
    

    此示例将eax 中包含的地址处的 32 位数量(“双字”)设置为 0。

    【讨论】:

    • 感谢马丁。我刚刚编译了一个简单的 C 代码并得到了 movl -8(%ebp), %eax cmpl -4(%ebp), %eax – 是 movl 中的“l”,而您所说的指标 cmpl 是 l=long =32位?如果是,您知道字节、2 字节和双字的指示符吗?谢谢
    • Anshuman 已经回答了这个问题——不同之处在于 AT&T 语法将操作数类型编码为指令助记符(movbmovwmovl),而 Intel 语法没有( mov)。这就是为什么 Intel 语法有时需要诸如 dword ptr 之类的说明符来解决歧义的原因。
    【解决方案2】:
    1. 无论操作数是 m8、m16 还是 m32,用于寻址内存位置的寄存器可以是 8、16 或 32 位 - 都是有效的 afaik。

    2. 要指定要从内存中读取多少位,您需要在地址前使用大小说明符byteworddword 之一。例如:

    idiv byte [bx] ; m8

    idiv word [bx] ; m16

    idiv dword [bx] ; m32

    【讨论】:

    • 感谢 Anshuman。我刚刚编译了一个简单的 C 代码并得到了 movl -8(%ebp), %eax cmpl -4(%ebp), %eax – 是 movl 中的“l”,而您所说的指标 cmpl 是 l=long =32位?如果是,您知道字节、2 字节和双字的指示符吗?谢谢
    • 是 - 字节是 b,字是 w,长(双字)是 l。这是助记符的 AT&T 语法。 (我在示例中使用了 Intel 语法)
    • okey 所以如果我使用解散程序生成程序集,生成的程序集是 Intel 还是 AT&T 语法?还是它也取决于我使用的拆卸器?
    • 大多数反汇编程序可以配置为产生一种特定的语法。使用 gdb 的 disassemble,您可以使用 set disassembly-flavor attset disassembly-flavor intel
    • 您不能在寻址模式下使用 8 位寄存器。 (而且您通常不希望使用比当前模式更窄的寄存器,即在 32 位模式下仅使用 32 位地址,但您可以使用 16 位地址大小。)给定模式,只有 2 种不同的地址大小是可能的。在大多数模式下,16 或 32,但在 64 位模式下只有 64 或 32。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2022-11-24
    • 2018-05-11
    • 2019-10-24
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    相关资源
    最近更新 更多