在C中调用函数时,寄存器和其他信息是如何保存的?
假设我有三个函数,在C中调用函数时,寄存器和其他信息是如何保存的?,c,cpu-registers,C,Cpu Registers,假设我有三个函数,f1(),f2(),和f3()。调用f1时,它将信息存储在CPU寄存器中(我想还有其他重要信息)。现在,根据编译时未知的条件,f1将调用f2或f3f2和f3使用非常不同的寄存器,其中一些寄存器可能与f1使用的寄存器重叠。以下推理正确吗 编译器知道特定函数在执行过程中需要哪个寄存器。因此,当f1调用f2或f3时,函数调用代码会保留那些f2或f3在堆栈上使用的寄存器,无论它们是否正被f1使用 或者编译器是否有其他机制来保留寄存器,以便返回的函数不会丢失其数据 “编译器知道特定函数在
f1()
,f2()
,和f3()
。调用f1
时,它将信息存储在CPU寄存器中(我想还有其他重要信息)。现在,根据编译时未知的条件,f1
将调用f2
或f3
f2
和f3
使用非常不同的寄存器,其中一些寄存器可能与f1
使用的寄存器重叠。以下推理正确吗
编译器知道特定函数在执行过程中需要哪个寄存器。因此,当f1
调用f2
或f3
时,函数调用代码会保留那些f2
或f3
在堆栈上使用的寄存器,无论它们是否正被f1
使用
或者编译器是否有其他机制来保留寄存器,以便返回的函数不会丢失其数据
“编译器知道特定函数在执行过程中需要哪个寄存器。”
不,它通常不知道这一点
一个原因是,函数可以来自编译器一无所知的(第三方)库。出于另一个原因,如果该函数调用另一个函数,以及另一个etetera呢
编译器只需将所有“可疑”寄存器推送到堆栈上,并在返回之前弹出它们。回想一下,编程语言是文档中的规范。例如,阅读 不存在于C中(换句话说,几乎过时的
寄存器
关键字不再与处理器寄存器相关)。它们只在机器代码中起作用(通常由C编译器生成)
但是,由给定编译器生成的代码(对于给定的指令集和目标系统)遵守一些约定,特别是和(请阅读Linux的管理示例)。这些约定定义了如何使用寄存器,以及哪些寄存器被调用者保存或调用者保存。这是安工作中很困难的一部分
编译器通常会发出代码,将一些寄存器的内容溢出到内存中。一个给定的寄存器可以用于多种用途(例如,它可以保存两个不同的变量,如果它们出现在同一函数的不同位置)
一般来说,调用约定不依赖于被调用函数(回想一下,您可以通过函数指针进行间接调用),而主要依赖于它的签名。我认为,正如其他人所说的那样,函数的参数通常是通过多个寄存器(此后在堆栈上)向下发送的。使用哪些寄存器取决于编译器–有关
gcc
的信息,请参阅GNU C/assembler:
值得注意的若干原则:
当编译器将您的C代码转换为汇编代码/操作码时,一系列函数的调用方式或调用顺序无关紧要。我不确定您到底在寻找什么,因为1。每个编译器可能执行不同的操作(因为这取决于目标机器)。这在编程语言标准和3中没有规定。它可能会根据调用约定和使用的优化而改变。当然,我正在尝试理解函数调用是如何工作的。我试图理解这样的事情:如果我在一个调用共享库函数的函数中,是什么保存了寄存器上的数据之类的东西。一个答案指出,由于编译器不知道该函数需要什么,所以由被调用函数本身来保存东西,不是吗?