为了理解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+用于指令而不是分解?
我正在查看汇编中的不同指令,我对如何决定不同操作数和操作码的长度感到困惑.
这是你应该从经验中得知的东西,还是有办法找出哪个操作数/运算符组合占用了多少字节?
例如:
push %ebp ; takes up one byte
mov %esp, %ebp ; takes up two bytes
Run Code Online (Sandbox Code Playgroud)
所以问题是:
在看到给定的指令后,如何推断出其操作码需要多少字节?
我是 x86_64 汇编编程的新手。我正在用 x86_64 程序集编写简单的“Hello World”程序。下面是我的代码,它运行得很好。
global _start
section .data
msg: db "Hello to the world of SLAE64", 0x0a
mlen equ $-msg
section .text
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, mlen
syscall
mov rax, 60
mov rdi, 4
syscall
Run Code Online (Sandbox Code Playgroud)
现在,当我在 gdb 中反汇编时,它会给出以下输出:
(gdb) disas
Dump of assembler code for function _start:
=> 0x00000000004000b0 <+0>: mov eax,0x1
0x00000000004000b5 <+5>: mov edi,0x1
0x00000000004000ba <+10>: movabs rsi,0x6000d8
0x00000000004000c4 <+20>: mov edx,0x1d
0x00000000004000c9 <+25>: syscall
0x00000000004000cb <+27>: mov …Run Code Online (Sandbox Code Playgroud)