【问题标题】:What do the instructions mov %edi and mov %rsi do?mov %edi 和 mov %rsi 指令有什么作用?
【发布时间】:2015-10-03 00:07:42
【问题描述】:

我编写了一个基本的 C 程序,它定义了一个整数变量 x,将其设置为零并返回该变量的值:

#include <stdio.h>

int main(int argc, char **argv) {
    int x;
    x = 0;
    return x;
}

当我使用 objdump(使用 gcc 在 Linux X86-64 上编译)转储目标代码时:

0x0000000000400474 <main+0>:    push   %rbp
0x0000000000400475 <main+1>:    mov    %rsp,%rbp
0x0000000000400478 <main+4>:    mov    %edi,-0x14(%rbp)
0x000000000040047b <main+7>:    mov    %rsi,-0x20(%rbp)
0x000000000040047f <main+11>:   movl   $0x0,-0x4(%rbp)
0x0000000000400486 <main+18>:   mov    -0x4(%rbp),%eax
0x0000000000400489 <main+21>:   leaveq 
0x000000000040048a <main+22>:   retq

我可以看到函数序言,但是在我们将地址 0x000000000040047f 处的 x 设置为 0 之前,有两条指令将 %edi 和 %rsi 移动到堆栈上。这些是干什么用的?

此外,与我们将 x 设置为 0 不同的是,GAS 语法中所示的 mov 指令没有后缀。

如果没有指定后缀,并且指令没有内存操作数,GAS 会根据目标寄存器操作数的大小推断操作数大小。

在这种情况下,-0x14(%rsbp)-0x20(%rbp) 是否都是内存操作数,它们的大小是多少?由于 %edi 是一个 32 位寄存器,是否将 32 位移动到 -0x14(%rsbp) 而由于 %rsi 是一个 64 位寄存器,所以将 64 位移动到 %rsi,-0x20(%rbp)

【问题讨论】:

  • 在这两个mov之后%rsiargv%ediargc
  • 有趣!据我了解,参数(即 argc 和 argv)在堆栈帧之前被推入堆栈(即 push %rbp)。这是否意味着 argc 和 argv 在 main 的堆栈框架内?
  • 其实我可能错了。编写另一个只调用您的main 函数的小函数,然后再次 objdump 文件,您将看到。
  • @GeorgeRobinson 在 x86_64 中有一个非常常用的调用约定,其中前 6 个参数被放入寄存器。 en.wikipedia.org/wiki/…

标签: c gnu-assembler disassembly


【解决方案1】:

在这种简单的情况下,你为什么不直接询问你的编译器呢?对于 GCC、clang 和 ICC,有 -fverbose-asm 选项。

main:
    pushq   %rbp    #
    movq    %rsp, %rbp  #,
    movl    %edi, -20(%rbp) # argc, argc
    movq    %rsi, -32(%rbp) # argv, argv
    movl    $0, -4(%rbp)    #, x
    movl    -4(%rbp), %eax  # x, D.2607
    popq    %rbp    #
    ret

所以,是的,他们使用“旧”帧指针方法将argvargv 保存到堆栈中,因为新架构允许直接从堆栈指针中减去/添加,因此省略了帧指针(@ 987654325@)。

【讨论】:

  • 这个未优化的代码没有使用-fomit-frame-pointer。它使用 RSP 下方的红色区域(一种软件约定,它是 x86-64 调用约定的一部分),但它使用 RBP 作为帧指针。从 386 开始,就可以相对于堆栈指针来引用内存了。这不是新的,但就像我说的不是这里发生的事情。
【解决方案2】:

Purpose of ESI & EDI registers?

基于此和上下文,我不是专家,但我的猜测是这些正在捕获main() 输入参数。 EDI 采用标准宽度,将匹配 int argc,而 RSI 采用 long,将匹配 char **argv 指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    相关资源
    最近更新 更多