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中?
由于代码只有几行,我希望能够逐步分解,以确认我是在正确的轨道上,也是为了弄清楚第二行的作用。谢谢。
答案 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
答案 1 :(得分:-1)
int a = 5; int* ptr = &a; int b = *a + 1;
您的示例是一个未定义的行为,因为您取消引用转换为指针的整数值(在本例中为5)并且它根本不会编译,因为此转换具有未知类型。
要使其正常工作,您需要先将其强制转换。 `int b = *(int *)a + 1;
第1行:加载值为a
的rax(在本例中为5)
第2行:取消引用此值(从地址5读取,因此您可能会得到分段错误)。此代码仅从堆栈加载,因为您使用-O0选项。