为什么在调用汇编函数时C不能将指针压入堆栈? [英] Why does C not push a pointer on the stack when calling a assembly function?

查看:88
本文介绍了为什么在调用汇编函数时C不能将指针压入堆栈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试从C调用汇编函数的经验.因此,我创建了一个小程序来计算所有数组元素的总和.

I am currently trying to get some experience with calling assembly functions from C. Therefore, I created a little program which calculates the sum of all array elements.

C代码如下:

#include <stdio.h>
#include <stdint.h>

extern int32_t arrsum(int32_t* arr,int32_t length);

int main()
{
    int32_t test[] = {1,2,3};
    int32_t length = 3;
    int32_t sum = arrsum(test,length);
    printf("Sum of arr: %d\n",sum);
    return 0;
}

汇编函数如下:

.text
.global arrsum
arrsum:

    pushq %rbp
    movq %rsp, %rbp

    pushq %rdi
    pushq %rcx

    movq 24(%rbp),%rcx
    #movq 16(%rbp),%rdi

    xorq %rax,%rax

    start_loop:
    addl (%rdi),%eax
    addq $4,%rdi
    loop start_loop

    popq %rcx
    popq %rdi

    movq %rbp , %rsp
    popq %rbp
    ret

我假设C遵守调用约定并将所有参数压入堆栈.确实,在位置24(%rbp),我能够找到数组的长度.我期望在16(%rbp)处找到指向数组的指针,但我只是找到了0x0.经过一些调试后,我发现C根本没有压入指针,而是将整个指针移到了%rdi寄存器中.

I assumed that C obeys the calling convention and pushes all arguments on the stack. And indeed, at position 24(%rbp) I am able to find the length of the array. I expected to find the pointer to the array at 16(%rbp), but instead I just found 0x0. After some debugging I found that C didn't push the pointer at all but instead moved the whole pointer into the %rdi register.

为什么会这样?我找不到有关此行为的任何信息.

Why does this happen? I couldn't find any information about this behavior.

推荐答案

C编译器将使用的调用约定取决于您的系统,传递给编译器的元数据和标志.听起来您的编译器正在使用System V AMD64调用约定,在此处进行了详细说明: https://zh-CN. m.wikipedia.org/wiki/X86_calling_conventions (暗示您在64位x86芯片上使用的是类似Unix的操作系统).基本上,在这个约定中,大多数参数都进入寄存器,因为它速度更快,并且64位x86系统具有足够的寄存器来完成此工作(通常).

The calling convention the C compiler will use depends on your system, metadata you pass to the compiler and flags. It sounds like your compiler is using the System V AMD64 calling convention detailed here: https://en.m.wikipedia.org/wiki/X86_calling_conventions (implying that you're using a Unix-like OS on a 64 bit x86 chip). Basically, in this convention most arguments go into registers because it's faster and the 64 bit x86 systems have enough registers to make this work (usually).

这篇关于为什么在调用汇编函数时C不能将指针压入堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆