Tag: calling convention

x86_64调用约定和堆栈帧

我试图理解GCC(4.4.3)为在Ubuntu Linux下运行的x86_64机器生成的可执行代码。 特别是,我不明白代码如何跟踪堆栈帧。 在过去,在32位代码中,我习惯于在几乎所有function中看到这个“序幕”: push %ebp movl %esp, %ebp 然后,在function结束时,也会出现“结局” sub $xx, %esp # Where xx is a number based on GCC’s accounting. pop %ebp ret 或简单地说 leave ret 这完成了同样的事情: 将堆栈指针设置为当前帧的顶部,就在返回地址的正下方 恢复旧的帧指针值。 在64位代码中,正如我通过objdump反汇编看到的那样,许多函数不遵循这个约定 – 它们不会推送%rbp然后将%rsp保存到%rbp,像GDB这样的调试器如何构建回溯? 我真正的目标是尝试找出一个合理的地址,当执行到达程序中的任意函数的开始时,可​​以将堆栈指针向下移动时,将其视为用户堆栈的顶部(最高地址)。 例如,对于“top”,argv的原始地址是理想的 – 但我无法从主要调用的任意函数访问它。 我起初以为我可以使用旧的回溯方法:追踪保存的帧指针值,直到保存的值为0 – 然后,下一个可以算作最高实际值。 (这与获取argv的地址不同,但它会 – 比如说,找出_start或任何_start调用的堆栈指针值[例如__libc_start_main]。)现在,我不知道如何获取64位代码中的等效地址。 谢谢。

函数调用中参数的评估顺序?

我正在研究C中的未定义行为,并且我发表了一份声明 函数参数的评估没有特定的顺序 但那么像_cdecl和_stdcall这样的标准调用约定呢,其定义(在一本书中)表明参数是从右到左进行评估的。 现在我对这两个定义感到困惑,根据UB,状态与另一个定义不同,这是根据调用约定的定义。 请certificate两者合理。

C / C ++中有哪些不同的调用约定,每个含义是什么?

C / C ++中有不同的调用约定: stdcall , extern , pascal等。有多少这样的调用约定可用,各自的含义是什么? 有没有描述这些的链接?