当我们在函数原型中放置_stdcall
(调用者不需要清除堆栈)时,它是由编译器还是链接器处理的?
答案 0 :(得分:2)
调用约定是如何来调用函数(参数准备和清理ctack的特定机器代码)和链接器处理哪个函数(函数在哪个地址)打电话。
通常,编译器会生成正确的代码并为确切的函数地址留下“占位符”,然后链接器会将实际地址放在那里。也就是说,有所谓的link-time code generation,其中两者都是由链接器完成的。
答案 1 :(得分:1)
调用约定会影响代码生成,因此编译器会处理它。链接器不需要知道它。
答案 2 :(得分:0)
在某些系统上,目标文件只是一堆数据,符号和补丁点。目标文件将告诉链接器链接代码的字节574应该被修补以包含符号Foo和Bar之间的差异的MSB,并且链接器将这样做,但是链接器没有超出列表的含义的概念。要进行的计算。
在其他一些系统上,链接器可能更多地涉及代码生成。例如,某些ARM处理器可以运行使用16位或32位指令集编码的代码。某些类型的代码只能使用32位指令集有效运行;有些将运行得足够,但使用16位集更紧凑。 ARM链接器知道使用每个指令集写入哪些例程,如果使用一个指令集编写的代码尝试调用使用另一个指令集编写的函数,则链接器将生成一个称为“单板”的包装器方法,并具有第一个函数调用。然后,胶合代码将执行调用另一种方法所需的操作。即使单板是“代码”,它也完全由链接器生成。
编译器和链接器之间确实没有固定的分工。我已经看到一些系统,其中“编译器”将程序转换为“中间”形式,并且链接器完成所有实际代码生成并根据事物在内存中的位置进行优化。如上所述,还有一些链接器只是一个“补丁处理器”。可能在这些极端之间的所有可想象的分工可能存在于某个系统的某个地方。