c - 从编译器到汇编器

标签 c assembly compiler-construction

我有一个关于汇编器的问题。我在想把多个参数作为实参的C函数是如何转化成汇编的。那么我的问题是,汇编中有没有把arguments作为参数来运行的子程序? 代码可能看起来像这样:

调用标签 1,R16。 其中R16为子程序输入参数。

如果不是这种情况,则意味着每次调用 C 函数时,它都会被组装到一个子例程中,并在其中自动替换与特定调用相关的参数。这基本上意味着无论何时调用 C 函数,编译器都会将其转换为内联函数,但肯定不是这种情况:D

那么哪个是对的呢? 多谢! :)

最佳答案

编译器使用一个“调用约定”,它可以特定于一个目标架构(x86、arm、mips、pdp-11 等)的编译器。对于具有“大量”通用寄存器的架构,调用约定通常从在寄存器中传递参数开始,然后使用堆栈,对于没有很多寄存器的架构,堆栈主要用于参数传递和返回.

调用约定是一组规则,如果每个人都遵守这些规则,你就可以将函数编译成对象,并将它们与其他对象链接起来,它们将能够相互调用函数或调用自己。

所以它有点混合了您的假设。为该函数构建的代码在某些方面是该函数的自定义代码,因为参数的数量和类型决定了哪些寄存器或多少堆栈被消耗以及如何消耗。同时,所有函数都遵循相同的公式,因此它们看起来相似多于不同。

例如,在 arm 上,您可能将三个整数传递给一个函数,对于我所见过的所有 arm 调用约定,它们都是如此(通常您会发现,即使它可能因编译器而异,但通常不会或在这种情况下arm 和 mips 以及其他一些他们试图为每个人规定约定,而不是编译器人员试图这样做)C 函数中的第一个参数将进入 r0,第二个进入 r1,第三个进入 r2。如果第一个参数是 64 位整数,那么 r0 和 r1 用于第一个参数,r2 获取第二个参数,r3 获取第三个参数,在使用堆栈的 r3 之后,堆栈上的参数顺序也由约定决定。因此,当使用相同的 C 原型(prototype)编译调用者或被调用者的代码时,双方都确切知道在哪里可以找到参数并构建汇编语言来执行此操作。

关于c - 从编译器到汇编器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35032284/

相关文章:

c - C免费的malloc的结构成员和结构

c - 读取原始音频文件

在共享库中不使用 PLT 调用另一个目标文件中的函数?

assembly - 无条件分支和无条件跳转(MIPS 中的指令)有什么区别?

assembly - 在 8086 中连接两个给定的字符串 + MOVSB 不起作用

iphone - 更新到 iPhone SDK 4.0 后,自己的库出现链接器错误(仅限模拟器)

compiler-construction - FPGA 编译器的中间表示

c - 结构中的无符号数据类型

c++ - 从 C/C++ 使用 SSL 访问 MySql

java - Java编译时错误: reached end of file while parsing