gpt4 book ai didi

c - 汇编:在调用函数之前加载有效地址的目的?

转载 作者:行者123 更新时间:2023-12-04 11:26:57 29 4
gpt4 key购买 nike

源代码:

 int main()
{
int i;
for(i=0, i < 10; i++)
{
printf("Hello World!\n");
}
}

转储函数的 Intel 语法 x86 汇编代码 main :
  1.  0x000055555555463a <+0>:     push   rbp
2. 0x000055555555463b <+1>: mov rbp,rsp
3. 0x000055555555463e <+4>: sub rsp,0x10
4. 0x0000555555554642 <+8>: mov DWORD PTR [rbp-0x4],0x0
5. 0x0000555555554649 <+15>: jmp 0x55555555465b <main+33>
6. 0x000055555555464b <+17>: lea rdi,[rip+0xa2] # 0x5555555546f4
7. 0x0000555555554652 <+24>: call 0x555555554510 <puts@plt>
8. 0x0000555555554657 <+29>: add DWORD PTR [rbp-0x4],0x1
9. 0x000055555555465b <+33>: cmp DWORD PTR [rbp-0x4],0x9
10. 0x000055555555465f <+37>: jle 0x55555555464b <main+17>
11. 0x0000555555554661 <+39>: mov eax,0x0
12. 0x0000555555554666 <+44>: leave
13. 0x0000555555554667 <+45>: ret

我目前正在研究“Hacking, The Art of Exploitation 2nd Edition by Jon Erickson”,我刚刚开始处理组装问题。

我有一些关于将提供的 C 代码翻译成汇编的问题,但我主要想知道我的第一个问题。

第一个问题:第 6 行的目的是什么? ( lea rdi,[rip+0xa2] )。

我目前的工作理论是,这用于保存下一条指令将跳转到的位置,以跟踪正在发生的事情。我相信这条线与 printf 相关源 C 代码中的函数。

所以本质上,它加载了 rip+0xa2的有效地址。 ( 0x5555555546f4 ) 进入寄存器 rdi , 简单地跟踪 printf 将跳转到的位置功能?

第二个问题:第11行的目的是什么? ( mov eax,0x0 ?)
我没有看到寄存器的先前使用, EAX并且不确定为什么需要将其设置为 0。

最佳答案

LEA 将指向字符串文字的指针放入寄存器,作为 puts 的第一个 arg。您要查找的搜索词是“调用约定”和/或 ABI。 (还有 RIP 相对寻址)。 Why is the address of static variables relative to the Instruction Pointer?

代码和数据之间的小偏移(仅 +0xa2 )是因为 .rodata部分被链接到与 .text 相同的 ELF 段中,而且你的程序很小。 (较新的 gcc + ld 版本会将它放在单独的页面中,因此它可以是不可执行的。)

编译器不能使用更短更高效的 mov edi, address在 Linux PIE 可执行文件中的位置无关代码中。它会用 gcc -fno-pie -no-pie 做到这一点
mov eax,0实现隐式 return 0main C99 和 C++ 保证。 EAX 是所有调用约定中的返回值寄存器。

如果您不使用 gcc -O2或更高,你不会得到像异或归零( xor eax,eax )这样的窥视孔优化。

关于c - 汇编:在调用函数之前加载有效地址的目的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59861048/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com