无法理解汇编代码中的基本指针计算

时间:2017-07-06 14:18:43

标签: c assembly stack x86-64

我试图通过执行反汇编程序来理解以下函数的汇编代码。我无法理解为什么所有操作都相对于基指针。

  1. 为什么rcxrdx的寄存器值移到内存位置偏移10和18? (mov 0x10(%rbp),%raxmov %rdx,0x18(%rbp))。

  2. 为什么返回值存储在 mov %rax,-0x8(%rbp)

  3. long absdiff(long x, long y)
    {
        long result;
        if (x>y)
            result = x-y;
        else
            result = y-x;
        return result;
    }
    0x00000001004010e0 <+0>:     push   %rbp
    0x00000001004010e1 <+1>:     mov    %rsp,%rbp
    0x00000001004010e4 <+4>:     sub    $0x10,%rsp
    0x00000001004010e8 <+8>:     mov    %rcx,0x10(%rbp)
    0x00000001004010ec <+12>:    mov    %rdx,0x18(%rbp)
    0x00000001004010f0 <+16>:    mov    0x10(%rbp),%rax
    0x00000001004010f4 <+20>:    cmp    0x18(%rbp),%rax
    0x00000001004010f8 <+24>:    jle    0x100401108 <absdiff+40>
    0x00000001004010fa <+26>:    mov    0x10(%rbp),%rax
    0x00000001004010fe <+30>:    sub    0x18(%rbp),%rax
    0x0000000100401102 <+34>:    mov    %rax,-0x8(%rbp)
    0x0000000100401106 <+38>:    jmp    0x100401114 <absdiff+52>
    0x0000000100401108 <+40>:    mov    0x18(%rbp),%rax
    0x000000010040110c <+44>:    sub    0x10(%rbp),%rax
    0x0000000100401110 <+48>:    mov    %rax,-0x8(%rbp)
    0x0000000100401114 <+52>:    mov    -0x8(%rbp),%rax
    0x0000000100401118 <+56>:    add    $0x10,%rsp
    0x000000010040111c <+60>:    pop    %rbp
    0x000000010040111d <+61>:    retq
    

1 个答案:

答案 0 :(得分:4)

1)为什么sub $0x10, %rsp

它实际上减去了16个字节,换句话说,它为两个“长”参数创造了空间。尝试打印'sizeof(long)',我很确定你会在你所使用的机器上得到'8'作为答案。

2)为什么要将寄存器值移到内存中?

同样,这是计算机将寄存器'rcx'和'rdx'中的两个长值加载到它在'1)'中创建的存储空间中的位置。 0x10和0x18有8个字节的差异。

3)为什么返回值存储在mov %rax,-0x8(%rbp)

它暂时存储,因为在离开函数之前,%rax寄存器用于其他一些计算。因此,如果它没有保存,它就会被覆盖,你可以看到在完成这些计算之后,该值再次加载到rax中。

mov%rax,-0x8(%rbp) <--- saving
jmp    0x100401114 <absdiff+52>
...
mov    %rax,-0x8(%rbp)
-0x8(%rbp),%rax" < -- retrieving

建议

我很确定你会发现这个链接真有帮助:

https://www.recurse.com/blog/7-understanding-c-by-learning-assembly