【问题标题】:add (assembly) instruction not working like I thought it should添加(汇编)指令不像我认为的那样工作
【发布时间】:2018-04-29 19:51:11
【问题描述】:

我的电话是add (%ecx,%esi,4),%edx。

我正在使用 gdb 查看代码并注意到如果使用 x/d 打印 ecx 中的值,它会打印 2(如果我使用 x/s 它会打印“/002”,如果这是相关的,则为 idk)。

那么寄存器esi持有0x2。

我认为 add 会像 edx = ecx + (esi * 4) 一样工作,应该是 0xA,但在这个 edx 之后是 0x6。

我查看了 add 语法,我相信我没有错,所以我想知道为什么它会显示为 0x6。

【问题讨论】:

  • 内存中的值被添加到edx。 ecx 和 esi 中的值仅与内存地址计算相关,即 address = ecx + esi*4; edx += value_at(address); ...gas 语法中的 () 表示内存访问(虽然不是在任何地方,mov 123,%eax 也是地址 @ 的内存访问987654331@,常量需要$)。不要指望汇编语法具有“逻辑”意义,指令行为具有“逻辑”意义,就某些高级语言而言,指令是在 CPU 中 1:1 硬件实现的,因此它们遵循硬件设计逻辑和语法有时是“原样”。
  • 只是不要猜测任何事情,始终为您感到困惑的任何事情找到适当的文档。如果你继续猜测,你会错 30% 次。
  • 如果您想要edx = ecx + (esi * 4),您可以使用lea (%ecx,%esi,4), %edx 进行地址数学运算,然后将结果放入寄存器而不是从中加载。 Using LEA on values that aren't addresses / pointers? 我很惊讶add (%ecx,%esi,4),%edx 这些输入没有出错;通常 0xA 不是有效地址。 (默认情况下,Linux 甚至不允许映射低 64kiB 的虚拟内存,因此 NULL 指针取消引用会出现段错误。)也许您正在调试内核/引导加载程序或使用 QEMU 的 gdb-stub 的东西?

标签: assembly x86


【解决方案1】:

首先你的程序集是AT&T语法,这意味着指令如下:

movl src,dest

给出的代码实际上像 this

那么寄存器esi持有0x2。我认为 add 会像 edx = ecx + (esi * 4) 一样工作,它应该是 0xA,但是在这个 edx 持有 0x6 之后。

它实际上是这样工作的:将edx的值添加到地址(ecx+esi*4)处的值

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多