为了理解Bulldozer为什么不合格我一直在关注Agner Fog的优秀微体系结构书籍,在第178页的推土机下它有本段。
最多三个前缀的指令可以在一个时钟周期内解码。对于超过三个的指令,会有很大的惩罚 前缀。带有4-7前缀的指令需要额外14-15个时钟周期 解码。带8-11前缀的指令需要20-22个时钟周期 额外的,12-14前缀的指令需要27 - 28个时钟周期 额外。因此,不建议延长NOP指令 有三个以上的前缀。此规则的前缀计数包括 操作数大小,地址大小,段,重复,锁定,REX和XOP 前缀。三字节VEX前缀计为一个,而两个字节 VEX前缀不计算在内。转义码(0F,0F38,0F3A)不计算在内。
当我搜索前缀时,我的技术定义远远超出了我的能力。或者,建议每条指令限制为4条与上述摘录相冲突。
所以简单来说,有人可以解释他们是/做什么,以及为什么你可能希望将多达14+用于指令而不是分解?
答案 0 :(得分:11)
通常你会根据需要使用尽可能多的指令和操作数来确定它。汇编程序会自动发出一些前缀,而其他人则可以手动使用。
他们提到的情况是多字节NOP
,传统上用于对齐填充,其中的想法是使用单个但适当长的指令来节省资源。显然,事实证明,使用更多的前缀只是为了保持单个指令可能比使用两个前缀更少的指令更糟糕。
此规则的前缀计数包括操作数大小,地址大小,段,重复,锁定,REX和XOP前缀。三字节VEX前缀计为一,而两字节VEX前缀不计。
示例:
mov ax, [foo]
的编码方式与mov eax, [foo]
相同,但前缀为66h
mov [eax], foo
的编码方式与mov [rax], foo
相同,但前缀为67h
(在64位模式下)mov [fs:eax], foo
的编码方式与mov [eax], foo
相同,但前缀为64h
。rep cmpsb
的编码与cmpsb
相同,但前缀为f3h
lock add [foo], 1
的编码方式与add [foo], 1
相同,但前缀为f0h
add rax, 1
的编码方式与add eax, 1
相同,但前缀为48h
add r8d, 1
与add eax, 1
相同,但前缀为41h
答案 1 :(得分:5)
“四个前缀”交易来自“前缀组”:
您可以重复前缀,但您不能(您可以,但行为未定义)使用同一组中的多个不同前缀。虽然这仅适用于第1组和第2组,但其他组中每组只有1件事。
像66 66 66 66 66 66 66 66 90
之类的东西是有效的(但解码速度可能很慢)。 2E 3E 00 00
(混合段覆盖)不是。
当必须执行字节时,堆栈前缀对于代码对齐非常有用,与使用nop
的填充不同,它不会花费执行时间。一次使用太多可能会花费解码时间。