FreeBSD vs Linux:内核调用约定的性能

int80h.org, the FreeBSD Assembly Language Tutorial

[The Linux Calling] convention has a great disadvantage over the Unix way, at least as far as assembly language programming is concerned: Every time you make a kernel call you must push the registers, then pop them later. This makes your code bulkier and slower.

继续谈论FreeBSD支持Linux惯例和“Unix惯例”

If you are coding specifically for FreeBSD, you should always use the Unix convention: It is faster, you can store global variables in registers, you do not have to brand the executable, and you do not impose the installation of the Linux emulation package on the target system.

对我来说,Linux方式会更笨重,速度更慢,这似乎很奇怪.好像有两种选择,

>只保存您需要保留的寄存器

>那些可能被系统调用破坏的易失性寄存器(据我所知ecx)
>或者,寄存器需要将适当的参数发送到内核以进行系统调用(可能是eax,ecx,edx,esi,edi,ebp)

>将100%的参数保存到堆栈上的内核中.

看起来FreeBSD就是Linux惯例最糟糕的情况.我错过了什么? FreeBSD约定(他们称之为“Unix方式”)如何不那么庞大和快速?

解决方法:

在我看来,这真的归结为作者的观点.

在FreeBSD(“Unix”)约定中,你推送堆栈上的参数,在EAX中指定系统调用号,并调用中断0x80(在堆栈上有一个额外的操作数,因为它希望从一个单独的函数调用).

在Linux i386约定中,将参数放在适当的寄存器中,并调用中断0x80.

笨重/慢的论点可能来自这样一个事实:使用Linux约定,调用者需要处理它对寄存器的使用.如果系统调用需要包含调用者关心的值的寄存器中的参数,则需要保留它们,这会导致额外的工作; see this example from the C library.在此示例中,系统调用需要EAX,EBX,EDX,EDI和ESI中的值;但调用者只关心保留EBX,EDI和ESI,所以它只会将它们推送到堆栈中.一般情况是quite a bit more complex(但这也是处理混合使用C语言和汇编语言的结果,试图在所有情况下生成最佳代码),但是在使用汇编语言编写时,这是您所指的网站的重点那不会是一个问题.

在我看来,这是六个半打:在FreeBSD约定中,你在所有情况下都会推送到堆栈,在Linux惯例中,你会根据你在做什么来推送到堆栈(或其他地方)通话网站.您可以争辩说,Linux约定可以实现更快的代码,因为您可以在寄存器中执行所有计算……正如Rob所指出的那样,在Linux上,寄存器仍然被推送(构建用于提供以下内容的struct pt_regs实例)处理系统调用的C函数的参数),因此Linux方面的总体成本要高于FreeBSD方面的成本.

在任何情况下,在讨论围绕系统调用的堆栈或基于寄存器的代码时讨论性能似乎相当迂腐,考虑到执行系统调用本身的成本.保存的任何周期当然都是好的,但相对的改善很小.

上一篇:从Linux下的逻辑分区挂载FreeBSD UFS


下一篇:linux – FreeBSD不是Unix.但它的Unix-Like Unix.那么主Unix在哪里阅读源代码?