混合汇编语言和C程序

时间:2010-11-05 17:45:44

标签: c assembly

我正在使用装配中的引导加载程序,我经常调用C函数来一次发送和接收一个字符。我正在使用的控制器似乎只有3个通用寄存器,它经常使用。除此之外,我将一些字节存储在固定的RAM位置。

所以,我的问题是: C函数会覆盖这些在Assembly中定义的RAM位置吗?

在进入这些C函数之前和之后,我正在执行相关寄存器的PUSH和PULL。

3 个答案:

答案 0 :(得分:1)

只要在进行c调用时保持堆栈中的先前值,就应该没问题。只需确保在调用之前将其推入堆栈并在返回后弹出堆栈。

答案 1 :(得分:1)

这完全取决于编译C代码的C调用约定。调用约定是调用者和被调用者如何在将数据传递到函数和之后返回值方面进行通信。这包括谁会在调用之前/之后执行诸如将寄存器备份到堆栈之类的东西,在调用C函数之前是否需要准备寄存器,是否可以保证寄存器将以它们的方式返回等等。

您需要了解C代码是如何编译的(使用Calling Convention设置)。请注意,这也是特定于体系结构的。可以在Wikipedia上找到不同调用约定的摘要和每个调用约定的描述:

http://en.wikipedia.org/wiki/Calling_convention

http://en.wikipedia.org/wiki/X86_calling_conventions

在x86上,cdecl和stdcall是最受欢迎的约定。 cdecl表示你的ASM代码应该进行清理,而stdcall表示被调用的函数负责它。如果您有C函数的源代码,我建议将必要的标志传递给编译器,使其成为“Callee清理”约定(通常是stdcall,但safecall和fastcall也是选项),这意味着您可以安全地调用C功能而不用担心寄存器损坏。

答案 2 :(得分:1)

如果我正确理解了您的问题,您会担心装配模块中使用的RAM位置与C模块中声明的某些变量重叠。您可以检查链接器输出的列表文件,以确定是否是这种情况。链接器列表文件将显示C模块使用的所有RAM地址,您可以将其与组装模块中使用的固定RAM位置进行比较。

请注意,如果链接器不自动生成列表文件,则必须通读链接器的文档以找到正确的命令行选项。