我在很多地方读到汇编语言通常不用于创建完整的程序,而是被其他程序用来使某些程序更高效,尤其是那些每秒调用几千次的程序。我想知道如何将少量的汇编代码合并到更大的程序中。
我认为可以制作一个小的可执行文件,然后从另一个程序运行,但这似乎效率低下。
然后我想到了 Visual Studio 的内联程序集,但那是微软特有的,似乎会有更好的方法。
那么如何在不创建单独的程序或使用 Visual Studio 内联汇编的情况下在更大的程序中使用少量的汇编代码呢?
我在很多地方读到汇编语言通常不用于创建完整的程序,而是被其他程序用来使某些程序更高效,尤其是那些每秒调用几千次的程序。我想知道如何将少量的汇编代码合并到更大的程序中。
我认为可以制作一个小的可执行文件,然后从另一个程序运行,但这似乎效率低下。
然后我想到了 Visual Studio 的内联程序集,但那是微软特有的,似乎会有更好的方法。
那么如何在不创建单独的程序或使用 Visual Studio 内联汇编的情况下在更大的程序中使用少量的汇编代码呢?
内联汇编并非特定于 Visual Studio - GCC 也支持它。内联汇编通常是将汇编合并到程序中的最简单方法。但是有几个问题 - 它会极大地影响代码的可移植性,并且一些编译器不支持它 - 例如,Microsoft 的 x64 编译器不支持它。
对于不支持内联汇编的编译器,或者当您想要包含所有特定于机器的代码时,您通常将汇编语言特定部分分离到它们自己的文件中,将汇编代码公开为您的 C++ 代码可以调用的函数。然后,您将它们组装并链接为构建的一部分。您的链接器不关心用于生成目标文件的语言 - 它可以将来自多种语言的目标文件组装到单个程序中。
然后我想到了 Visual Studio 的内联程序集,但那是微软特有的,似乎会有更好的方法。
每个编译器都支持某种形式的内联汇编,尽管方式通常略有不同。
因此,如果您需要使用内联汇编,请将每个片段封装在一个小函数中。然后,在移植到另一个编译器时,您可以毫不费力地重新实现这些函数。
这是一个示例(GCC):
__asm__ ("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"movb %ah, (%ebx)");
对于 Microsoft 内联汇编,关键字是 __asm,汇编代码用大括号括起来,它不是字符串,目标寄存器现在位于左侧。
微软示例:
int foo(void) {
__asm{
mov eax,100 ; Moves 100 into eax!
leave
ret
};
}
更多信息的链接
内联汇编说明和参考:http ://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
IBM 教程,特定于 x86:http ://www.ibm.com/developerworks/linux/library/l-ia.html
对于像内部循环这样的少量代码,通常使用内联汇编来完成。这绝对不是微软特有的!(GCC 和几乎所有现代编译器也都支持它,尽管语法有不同的变化)。
对于较大的代码块(例如,操作系统的引导加载程序),它通常会放在一个单独的源文件中(就像您对每种语言使用多个源文件一样),然后与程序的其余部分链接使用链接器。
请记住,现在汇编主要用于操作系统,因为编译器现在已经足够好,将它用于游戏等内部循环并没有多大帮助(而且它根本不能移植到不同的架构)。它主要用于非常低级的东西,例如硬件中断和设置分页(虚拟内存)。