我总是通过汇编编写来了解C编程语言中某些函数是如何优化的。如果这句话听起来有些误导,请告诫我。
所以,我会清楚地说明:当你在UNIX / C系统上调用像strlen这样的函数时,你调用的实际函数是用汇编编写的?你能以某种方式将程序集编写到C程序中,还是外部调用情况?能够做到这一点是C标准的一部分,还是特定于操作系统的东西?
答案 0 :(得分:34)
C标准规定了每个库函数必须执行的操作,而不是它是如何实现的。
几乎所有已知的C实现都被编译成机器语言。 C编译器/库的实现者如何选择实现strlen
之类的函数。他们可以选择在C中实现它并将其编译为对象,或者他们可以选择在汇编中将其编写并将其组装到对象中。或者他们可以通过其他方式实现它。只要您在致电strlen
时获得正确的效果和结果,这无关紧要。
现在,实际上,许多C工具集都允许您编写内联汇编,但这绝对不是标准的一部分。任何此类设施都必须作为C标准的扩展。
答案 1 :(得分:17)
在道路的最后,汇编的程序和程序都是机器语言,所以他们可以互相打电话。这样做的方法是让汇编代码使用与用C编写的程序相同的调用约定(准备调用,准备参数等的方法)。可以找到x86处理器的流行调用约定的概述{{ 3}}
答案 2 :(得分:8)
许多(大多数?)C编译器确实支持inline assembly,但它不是标准的一部分。也就是说,没有严格需要编译器支持任何此类事情。
首先,要认识到程序集主要只是人类(半)可读的机器代码,而C最终仍然是机器代码。
“调用”C函数只生成一组指令,根据一些已建立的调用约定准备寄存器,堆栈和/或其他一些与机器相关的机制,然后跳转到被调用函数的开头。 / p>
汇编代码块可以符合适当的调用约定,从而生成一小撮机器代码,这是最初用C编写的另一个机器代码块能够调用的。当然,反过来也是可能的。
调用约定,汇编过程和链接过程(将程序集生成的目标文件与C生成的目标文件链接)的细节可能在平台,编译器和链接器之间变化很大。适合您所选平台的精美装配教程可能会涵盖这些细节。
我碰巧喜欢以x86为中心的PC Assembly Tutorial,它专门用于处理接口汇编和C代码。
答案 3 :(得分:4)
当C代码由gcc编译时,它首先被编译为汇编程序指令,然后再将其编译为二进制机器可执行文件。您可以通过指定-S
来查看生成的汇编程序指令,如gcc file.c -S
。
汇编程序代码只是通过C-to-assembler编译的第一阶段,然后与从C编译的代码无法区分。
答案 4 :(得分:1)
一种方法是使用内联汇编程序。这意味着您可以将汇编代码直接编写到C代码中。具体语法是特定于编译器的。例如,请参阅GCC syntax和MS Visual C++ syntax。
答案 5 :(得分:0)
您可以在C代码中编写内联汇编。其语法高度针对特定于编译器,但通常使用asm
关键字。查看内联汇编以获取更多信息。