切换QWORD以获取DWORD并对其执行计算

时间:2017-10-16 13:10:57

标签: c assembly compilation

mov  rax,QWORD PTR [rbp-0x10]

mov  eax,DWORD PTR [rax]

add  eax,0x1

mov  DWORD PTR [rbp-0x14], eax

下一行用C语言编写,在GNU / Linux环境下用GCC编译。

汇编代码用于int b = * a + 1;。

...

int a = 5;

int* ptr = &a;

int b = *a + 1;

取消引用 a 的地址并添加1。之后,存储在新变量下。

我不明白该汇编代码中的第二行。这是否意味着我切断QWORD以获取DWORD(QWORD的一部分)并将其存储到eax中?

由于代码只有几行,我希望能够逐步分解,以确认我是在正确的轨道上,也是为了弄清楚第二行的作用。谢谢。

2 个答案:

答案 0 :(得分:1)

  

我不明白的是汇编代码中的第二行。这是否意味着我切断QWORD以获取DWORD(QWORD的一部分)并将其存储到eax中?

不,第二行取消引用它。没有将qword分成两个双八分。 (Writing EAX zeros the upper 32 bits of RAX)。

它碰巧使用了它用于指针的相同寄存器,因为它不再需要指针。

在启用优化的情况下进行编译;如果gcc不是一直存储/重新加载,那么更容易看到发生了什么。 (How to remove "noise" from GCC/clang assembly output?

int foo(int *ptr) {
    return *ptr + 1;
}

    mov     eax, DWORD PTR [rdi]
    add     eax, 1
    ret

On Godbolt

答案 1 :(得分:-1)

int a = 5;

int* ptr = &a;

int b = *a + 1;

您的示例是一个未定义的行为,因为您取消引用转换为指针的整数值(在本例中为5)并且它根本不会编译,因为此转换具有未知类型。

要使其正常工作,您需要先将其强制转换。 `int b = *(int *)a + 1;

https://godbolt.org/g/Yo8dd1

汇编代码说明:

第1行:加载值为a的rax(在本例中为5) 第2行:取消引用此值(从地址5读取,因此您可能会得到分段错误)。此代码仅从堆栈加载,因为您使用-O0选项。