【问题标题】:Inline assembly or separate assembly files [closed]内联汇编或单独的汇编文件[关闭]
【发布时间】:2018-05-23 18:33:39
【问题描述】:

我目前正在尝试进入操作系统开发,主要关注来自OSDev 的文章和教程。就像现在的操作系统一样,我有多个我需要的程序集文件,例如启用分页和设置长模式。

虽然我确定唯一需要在自己的文件中分离的汇编代码是引导汇编文件,但我很好奇如何在用 C 编写的操作系统中处理汇编的实践和“标准”。将汇编程序与 C 分开是否方便,或者是否有原因,例如Linux 将大部分汇编代码封装在 C 函数中并使用 asm volatile 指令调用它们?

我看不出有什么不同,因为您可以通过将值移动到eax 寄存器中来从汇编中返回结果,或者在使用asmasm volatile 时,您可以指定参数和输出操作数的存储位置结果。但是,您总是需要使用\n\n\t 来分隔多个指令。

到目前为止,我只发现了在一个较大的项目中处理汇编的不同方法,但不知道为什么有些人选择将汇编代码与 C 或 C++ 分开,以及为什么有些人选择在整个程序中使用内联汇编.

我希望你能给我一些关于在这个主题上使用的不同方法的见解。

【问题讨论】:

  • 您可以通过将值移动到 eax 寄存器中来返回汇编结果。这可能看起来有效,但只是偶然有效。除非您使用输入和输出操作数告诉编译器您在做什么,否则您不能安全地使用 GNU C 内联汇编。当编译器将您的函数内联到调用者中时,它将中断。请参阅this answer 以获取有关内联 asm 的更多链接,以及错误使用它可能带来的麻烦。

标签: c++ c assembly


【解决方案1】:

接口、协议和约定

在纯汇编语言项目中,您需要设置传递值和返回值的协议或约定。

在将汇编语言函数与 C 或 C++ 混合使用时,您需要遵循所使用的编译器所规定的 C 或 C++ 的参数传递约定。

一些编译器可能使用在 R0 中传递第一个参数的约定,而其他编译器可能在 R0 中传递最后一个参数。一些编译器可能会将变量放在堆栈上而不使用寄存器。其他人可能会使用寄存器来存储一些参数,而其余参数则在堆栈中。

内联与单独的汇编函数

一个问题是便携性。汇编语言是特定于处理器的。例如,ARM 程序集没有 EAX 寄存器。英特尔组件没有 R10 寄存器。使用内联汇编时,汇编必须根据处理器而改变,其中包括修改高级语言函数以考虑所有目标处理器。当实现为单独的汇编函数(文件)时,移植到其他处理器时只需要换出文件。

恕我直言,纯汇编函数比混合的 C 和内联汇编更容易阅读。

操作系统中高级语言使用指南

应尽量减少汇编语言的数量。汇编语言需要更长的时间来开发(打字和调试,更多的行==高可能的注入缺陷),而高级语言的生产力更高,风险更低。

更喜欢用高级语言编写整个操作系统。让这个版本运行良好。用汇编函数替换 C 函数以提高效率,或者在需要特定的汇编语言指令时。

【讨论】:

  • 这听起来很合理。此外,用高级语言编写更多内容也应该避免有关汇编的问题,因为编译器将程序/文件转换为编译器所针对的体系结构。因此,如果没有与 C 等效的代码,或者您需要为操作系统操作某些特定寄存器,那么只有操作系统的某些(少数)部分应该用汇编编写?
  • 内联 asm 可以......好吧,内联,而对 asm 例程的调用必须始终产生调用/ret 的成本,所以就是这样。但大多数情况下,我认为you should not use inline asm.
猜你喜欢
  • 2018-05-03
  • 2012-10-20
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 2019-05-11
相关资源
最近更新 更多