文章目录
- x32 cdecl调用约定
- x64 System V AMD64 ABI调用约定
规定函数调用时如何传递参数,如何返回值,如何进行栈管理
x32 cdecl调用约定
参数从右往左依次压入栈中,返回值存入eax寄存器中,由调用者清理栈上的参数。
测试程序:
#include<stdio.h>
int main() {
printf("%d, %d, %d, %d, %d, %d\n", 1, 2, 3, 4, 5, 6);
return 0;
}
// 编译
// gcc test.c -o test_32 -m32
// -o test_32:指定输出文件名为 test_32。
// -m32 指示编译器生成 32 位架构的目标代码。
查看程序.text
节区反汇编代码
objdump -d -j .text ./test_32 -M intel
objdump是一个用于显示二进制文件(例如 ELF 格式的文件)信息的命令行工具。在这个例子中,使用了以下选项和参数:-d:反汇编目标程序的代码部分。-j .text:只处理名为 .text 的节区(segment),这通常包含程序的可执行机器代码。./test_32:指定要分析的二进制文件名(这里是一个名为 test_32 的文件)。-M intel:设置输出格式为 Intel 风格。默认情况下,objdump 使用 AT&T 风格的汇编语言表示。因此,此命令将会把名为 test_32 的二进制文件中 .text 节区的内容反汇编成 Intel 风格的汇编语言代码。
查看main部分函数,可以发现传参是从右往左依次压入栈中。
x64 System V AMD64 ABI调用约定
参数前六个参数由寄存器传递,寄存器顺序为rdi、rsi、rdx、rcx、r8、r9,超过的参数由栈传递,返回值传入rax寄存器,栈由调用方管理。
#include<stdio.h>
int main() {
printf("%d, %d, %d, %d, %d, %d\n", 1, 2, 3, 4, 5, 6);
return 0;
}
# gcc test.c -o test_64
查看汇编代码
objdump -d -j .text ./test_64 -M intel
如下图所示,前6个参数通过寄存器传参,后面的参数压入栈中