为什么glibc库使用汇编?

问题描述 投票:0回答:2

Glibc 和系统调用层文档解释了 glibc 如何进行系统调用。

在其中一个示例中,检查了代码并显示,glibc 执行的最后一条指令实际上执行系统调用(意味着对 cpu 的中断),是用汇编语言编写的。

那么为什么 glibc 是汇编的一部分呢?在汇编中编写这一小部分是否有某种优势?

此外,运行时的共享库已经编译为正确的机器代码?

那么为什么在编译之前使用两种不同的语言会有任何优势呢?

c gcc assembly glibc
2个回答
10
投票

答案非常简单 - 由于 C 不涵盖系统调用(因为它一般不涵盖任何物理硬件,并且更喜欢用抽象机器来表达自己),因此没有 C 构造

glibc
可以使用执行系统调用。

有人可能会说编译器可以提供一种内在函数来做到这一点,但由于在 Linux 中 glibc 实际上是编译器工具套件的一部分(也包含 CRT),因此实际上没有必要,glibc 可以完成这项工作.

此外,最后但并非最不重要的一点是,在现代 CPU 中,系统调用通常不是中断。相反,它是一条特定指令(x86_64 中的

syscall
)。


5
投票

我想回答你的这个问题:

另外,运行时的共享库已经正确编译为机器代码了吗? 那么为什么在编译之前使用两种不同的语言会有任何优势呢?

SergeyA 正确地指出,没有任何 C 构造(即使具有所有 GCC 扩展)都会导致编译器发出

syscall
指令。这并不是 C 库应该做的唯一不能纯粹用 C 编写的事情:
setjmp
longjmp
makecontext
setcontext
的实现,“入口点”代码调用
main
,从信号处理程序返回时返回的“蹦床”,以及其他几个低级位都需要一点点手写汇编。 (练习:它们有什么共同点?)

但是将汇编语言混合到主要用 C 编写的程序中还有另一个原因。 这是 glibc 中 x86-64 的

memcpy
的几种实现之一。它是 3100 行手写的汇编语言和预处理器宏。它的作用可以用四行 C 语言来表达。为什么有人会这么麻烦呢? 速度。编译器总是越来越接近,但在从关键的最内层循环中挤出每个最后可能的循环时,它们还没有完全击败人类大脑。 (值得一提的是,在 2018 年初,glibc 开发人员花了很多时间用 C 替换 math.h
 函数的手写汇编实现,因为编译器 
have 已经赶上了这些,而且 C 的可维护性要高得多.)

还有第三个答案,它与 glibc 不是特别相关,但在其他地方出现了很多,是你的程序中可能有两种不同的语言,因为它们中的每一种都更擅长解决你的问题。统计语言 R 大部分是用 C 实现的,但它的一堆数学原语是(或者曾经是,我有一段时间没有检查过)用 FORTRAN 编写的,因为 FORTRAN 仍然是数值计算奇才思考的语言。 FORTRAN 被编译为机器代码,原则上你

可以用 C 重写所有的 FORTRAN,但没有人愿意。

© www.soinside.com 2019 - 2024. All rights reserved.