【问题标题】:Why does glibc library use assembly为什么glibc库使用汇编
【发布时间】:2019-01-23 20:21:49
【问题描述】:

我在看这个页面:https://sys.readthedocs.io/en/latest/doc/01_introduction.html
这将解释 glibc 如何进行系统调用。
在其中一个示例中,检查了代码并显示,最后一条指令 glibc 实际上执行系统调用(意味着对 cpu 的中断)是用汇编编写的。 .. 那么为什么 glibc 是汇编的一部分呢?在汇编中编写那一小部分是否有某种优势?
另外,运行时的共享库已经编译为机器码对吗?
那么为什么在编译之前使用两种不同的语言会有任何优势呢?谢谢。

【问题讨论】:

  • 编译器不支持为CPU部分的中断生成机器码。
  • 如果不是汇编写的,用什么C语句?
  • 为什么 C 标准库的某些部分以低级语言实现令人惊讶?各种高级语言通常在低级语言中实现。 Python、Java、Ruby、Perl 和许多其他都属于这一类。

标签: c gcc assembly glibc


【解决方案1】:

答案非常简单——因为 C 不涵盖系统调用(因为它通常不涵盖任何物理硬件,并且更喜欢用抽象机器来表达自己),所以没有 C 构造 glibc可以用来执行系统调用。

有人可能会争辩说,编译器可以提供一种内在功能来做到这一点,但由于在 Linux 中 glibc 实际上是编译器工具套件的一部分(也包含 CRT),因此实际上不需要它,glibc 可以做到工作。

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

【讨论】:

  • 您的意思是“glibc 不能使用任何 C 构造”,而您有“glibc 可以使用 ...”?
  • @zwol,是的,这非常不清楚,感谢您指出。我改写了,希望现在更好。
  • @SergeyA... 我明白并理解您所说的 glibc 不想专门涵盖任何硬件的意思....但是,为了学习,我们假设您想编写一个用于 x86 平台系统调用的 glibc 的 C 函数,你能做到吗?因此,您可以使用另一个可以执行相同操作的 C 函数,而不是将程序集放在 glibc 中。我知道这将毫无意义,但我只是好奇它是否可能。谢谢。
  • @hescobar1013 你可以写一堆函数,就像list item 3 of this old answer of mine 中的函数一样,事实上这正是 glibc 所做的(由于历史原因,隐藏在大量宏下)——但是有函数体中的内联汇编操作,这是不可避免的。
  • @zwol ....谢谢你的链接,这个答案也很有趣......所以我明白了,在 glibc 和 gcc 的上下文中,出于多种原因需要组装,其中之一是 glibc 不想关心硬件级别的“东西”并且不可知论......但是为了学习,在 glibc 和 gcc 之外,是否可以编写一个 C 库和一个x86平台的C编译器,可以放弃使用汇编吗?因此,您可以制作一个能够理解将“int 0x80”或类似内容转换为机器代码以执行系统调用的编译器,对吗?谢谢。
【解决方案2】:

我想解决你的这个问题:

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

SergeyA 正确地指出,没有任何 C 构造(即使具有所有 GCC 的扩展)会导致编译器发出 syscall 指令。这不是 C 库应该做的唯一不能完全用 C 编写的事情:setjmplongjmpmakecontextsetcontext 的实现,“入口点”代码调用main,从信号处理程序返回时返回的“蹦床”,以及其他几个低级位都需要一点点手写汇编。 (练习:它们有什么共同点?)

但是还有另一个原因将汇编语言混合到一个主要用 C 编写的程序中。This is one of the several implementations of memcpy for x86-64 in glibc。它是 3100 行手写汇编语言和预处理器宏。它的作用可以用四行 C 来表达。为什么有人会那么麻烦? 速度。 编译器总是越来越近,但在从关键的最内层循环中挤出每一个最后可能的循环时,它们还没有完全击败人脑。 (值得一提的是,在 2018 年初,glibc 开发人员花了很多时间用 C 替换 math.h 函数的手写汇编实现,因为编译器赶上了这些,而 C更易于维护。)

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

【讨论】:

  • “FORTRAN 仍然是数值计算向导思考的语言”——这不仅仅是他们思考哪种语言的问题——FORTRAN 中缺少指针别名允许进行更积极的优化,通常会导致在更快的机器代码中。
  • @EmployedRussian 我认为原则上你可以通过仔细使用restrict在C语言中获得相同的优化级别,但无论如何这是一个好点:学习如何“在 C 中思考”将涉及学习所有类似的东西,你必须在 C 中而不是在 FORTRAN 中做,所以转换成本甚至比乍看之下还要高。
猜你喜欢
  • 2014-09-29
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 2016-09-07
  • 2013-06-23
  • 2011-11-09
  • 2011-01-29
相关资源
最近更新 更多