3 汇编的函数调用

浪尽此生 提交于 2020-02-26 19:21:38

3 汇编的函数调用

3.1 无参数和返回值的函数调用

void func_void()
{
    printf("func, no param, no return value\n");
}

// func_void();
asm ("call func_void");  // call指令调用函数,该函数为C命名风格,C++编译则需使用C++名称。

3.2 调用函数并获取返回值

int func_get_value () {
    int a = 11;
    int b = 12;
    return a + b;
}


int a ;
// a = func_get_value();

asm (
    "call func_get_value\n\t"
    "mov %%eax, %0\n\t"      // 按照调用约定,EAX/RAX寄存器存放返回值。
    : "=m" (a)
);
printf("%d\n", a);   // output: 23

3.3 调用参数数目在6个以内的函数

  • 根据System V X86_64调用约定,6个以内(含)的参数,放入寄存器。
int func_add(int a, int b)
{
        return a + b;
}

int c = 0;
// c = func_add(100 , 200);
asm (
        "mov $100, %%edi\n\t"   // 根据调用约定,寄存器edi放入第一个参数
        "mov $200, %%esi\n\t"   // esi放入第二个参数
        "call func_add\n\t"
        "mov %%eax, %0\n\t"
        : "=m" (c)
);
printf("%d\n", c); // output: 300

3.4 调用参数数目在6个以上的函数

  • 根据System V X86_64调用约定,6个以内(含)的参数,放入寄存器,第7个参数以上则写入栈。
int func_add8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
{
    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
}

void test_add8()
{
int s = 0;
// s = func_add8(1, 2, 3, 4, 5, 6, 7, 8);
asm (
        "mov $1, %%edi\n\t"    // 按调用约定先将前6个参数写入对应的寄存器
        "mov $2, %%esi\n\t"
        "mov $3, %%edx\n\t"
        "mov $4, %%ecx\n\t"
        "mov $5, %%r8d\n\t"
        "mov $6, %%r9d\n\t"
        "pushq $8\n\t"         // 后2个参数逆序压栈,压栈后栈顶指针rsp会上移
        "pushq $7\n\t"
        "call func_add8\n\t"   // 调用函数
        "addq $16, %%rsp\n\t"  // 栈顶指针复位,回复到之前上移前的位置。
        "mov %%eax, %0\n\t"
        : "=m" (s)
);
printf("s = %d\n", s);  // output: 36
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!