已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新问题,以便editing this post可以用事实与引用来回答.
3天前关闭。
Improve this question
我时不时地在某个地方读到,在CPU的所有指令中,只有很少一部分是在大部分时间使用的,上一次是here,作者写道:“只有少数几条不同的指令占所有执行操作的90%”。
最常用的指令是什么?我对x86-64和arm 64最感兴趣。
已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新问题,以便editing this post可以用事实与引用来回答.
3天前关闭。
Improve this question
我时不时地在某个地方读到,在CPU的所有指令中,只有很少一部分是在大部分时间使用的,上一次是here,作者写道:“只有少数几条不同的指令占所有执行操作的90%”。
最常用的指令是什么?我对x86-64和arm 64最感兴趣。
1条答案
按热度按时间w6mmgewl1#
这将因操作系统、编译器、编译器版本、编程语言以及可能的目标架构扩展而异。这还取决于您在"相同"指令与"不同"指令之间的界限。
在arm64上,如果你认为
movz w0, 0
和movz w0, 1
是不同的,那么你可以取任何二进制,将它分成4字节的块,以十六进制打印并通过sort | uniq -c
运行。如果你认为所有的
movz
都是同一条指令,那么问题就来了:movz w0
和movz x0
是否相同?如果答案是肯定的,还有其他的指令,比如add
,它们有不同的形式,第三个操作数是寄存器或立即数。索引模式引入了额外的效果。除此之外,还有一些伪指令,如mov
,可以根据操作数编码为movz
、movn
或orr
。但让我们看一个具体的例子:macOS 12.6.1上的
/bin/bash
二进制文件。arm64e片的
__TEXT.__text
部分有118587条指令,如果我们将其全部分解,并尝试通过以下命令将所有立即数替换为...
,将所有通用寄存器以及(w|x)zr
和(w)sp
替换为rN
,将所有浮点寄存器替换为fN
来对其进行规范化:然后按频率对结果进行排序:
然后在
ret
指令处选择一个任意截止值,我们得到:这相当于112015条指令,占指令总数的94.5%。
retab
都是ret
,而pacibsp
、autibsp
和paciza
根本不存在。brk
的出现都是在autibsp
之后,这是Apple为了解决FEAT_PAuth
架构扩展的结构性弱点而被迫做出的编译器更改。其余的出现很可能是源代码中__builtin_trap()
的调用。nop
是非常常见的。这是由于PC相对寻址,编译器发出两个或三个类似adrp x0, ...; add x0, x0, ...
的指令,如果目标地址足够接近指令,则可以在链接到adr x0, ...; nop
时优化这些指令。nop是否"运行",或者是否只是从指令流水线中删除,这是有争议的。invalid
非常常见。这些是在使用它们的函数之后找到的跳转表。它们是数据,而不是代码,因此实际上从未运行过。stp
和ldp
。编译器通常将浮点寄存器用于memcpy和memset操作,一是因为这些寄存器可以容纳多达128位,二是因为它避免了溢出通用寄存器,通用寄存器比浮点寄存器更有可能已经被分配。至少在bash
这样的命令行二进制文件中是这样的。我希望在操作系统内核和嵌入式固件中有类似的情况,但在图形相关代码或机器学习中,这可能看起来非常不同。cmn
指令都会检查值-1
。这很可能是C语言中API设计的结果,而不是架构所固有的。现在,这取决于你是否想减少其中的一些指令。但总的来说,我认为模式是明确的:
弥补了绝大多数指令,这是有意义的,因为有了这些构建块,你基本上可以做任何事情。几乎所有其他指令都是对这些指令的某种优化,它们更适合利基市场,因此出现的频率更低。剩下的指令是特定于体系结构的,并暴露了你无法通过其他方式获得的东西,如
brk
或msr
。但这种情况将更加罕见。无论你看什么架构,这种情况都很可能发生。