【问题标题】:Assembly add with hex and multiple argument, then compare汇编添加十六进制和多个参数,然后比较
【发布时间】:2016-09-20 00:39:20
【问题描述】:
add -0x4(%r12), %eax
cmp %eax, %r12

我在汇编中得到了这两行。

我的猜测是你从 r12 中的值减去 4,然后将它添加到 eax。

r12 是从原来的值继续为 -4,还是保持原来的值?

例如,如果 r12 = 5,并且 eax = 3,则 add 函数将导致 eax = 4;
r12 还是 5 还是 1?

【问题讨论】:

  • 我有点想把标题编辑成通用的东西,现在我已经发布了一个答案,展示了如何测试任意代码片段。人力资源管理系统。这通常与一个好的标题应该是相反的。

标签: assembly x86 x86-64 att


【解决方案1】:

您可以自己在 gdb 中单步执行,看看它做了什么。设置 gdb 以显示上一步更改的寄存器(例如 layout reg,参见底部的 tag wiki)。

由于 %r12 需要是 ADD 的源操作数的有效指针,因此将其放入 foo.S

.globl _start
_start:
    mov   %rsp, %r12               # added this instruction: r12 is now a valid pointer to stack memory, since we copy the stack pointer into it

    add   -0x4(%r12), %eax
    # cmp   %eax, %r12             # operand-size mismatch is an error

    cmp   %eax, %r12d              # 32-bit compare
    cmp   %rax, %r12               # 64-bit compare.  upper 32 of RAX is zero from writing EAX in the add instruction

    # your program will segfault here because we don't make an exit() system call, and instead keep executing whatever bytes are next in memory.

将它与gcc -g -nostdlib foo.S 组装成一个静态二进制文件。 _start is the default entry point.

运行gdb ./a.out:

(gdb) layout reg
(gdb) b _start
(gdb) r
(gdb) si          # step instruction, 
# repeat as necessary and watch gdb highlight changed registers.

我喜欢set disassembly-flavor intel 而不是 AT&T 语法,但如果你喜欢(或想要/需要学习 AT&T 语法),那就不要那样做。

提示,CMP doesn't modify either of its operands,ADD 仅使用 R12 作为寻址模式来加载 4 字节的源数据。

EAX 的最终值取决于内存中的内容。

【讨论】:

    【解决方案2】:

    这不会改变r12;它只是用它来计算地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      • 2012-08-16
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      相关资源
      最近更新 更多