Jol*_*151 2 cpu x86 computer-science instruction-set cpu-architecture
我学到了一个地址,两个地址和三个地址指令,但是现在我想知道x86使用什么样的地址指令?
x86是一个寄存器机器,其中任何指令的最多1个操作数可以是显式存储器地址而不是寄存器,使用类似的寻址模式[rdi + rax*4]
.(有一些指令可以有2个内存操作数,其中一个或两个都是隐式的,但是:x86指令需要两个(或更多)内存操作数?)
典型的x86整数指令有2个操作数,都是显式的,就像add eax, edx
它们一样eax+=edx
.
Legacy x87 FP代码使用带有x87堆栈的1操作数指令,就像faddp st1
x87 stack(st0
)的顶部是隐式操作数一样.SSE2是x86-64的基线,因此不再广泛使用.
现代FP代码使用SSE/SSE2 2操作数指令addsd xmm0,xmm1
或3操作数AVX编码vaddsd xmm2, xmm0, xmm1
有x86指令有0,1,2,3甚至4个显式操作数.
存在多种指令格式,但显式的寄存器/存储器操作数通常以跟随操作码字节的ModR/M字节编码.它有3个字段:
reg
,寄存器间接[reg]
,[reg + disp8],[reg+disp32]
).具有位移位的模式表示那些字节遵循ModR/M字节.大多数指令至少有2种编码,reg/memory destination或reg/memory source.如果你想要的操作数都是寄存器,你可以使用操作码,add r/m32, r32
或者add r32, r/m32
.
通用指令还有其他操作码用于即时源代码形式,但通常它们使用reg
ModR/M中的字段作为额外的操作码位,因此您仍然只能获得2个操作数add eax, 123
.一个例外是imul
用286添加的直接形式,例如imul eax, [rdi + rbx*4], 12345
.它不是与其他立即指令共享编码空间,而是在ModR/M中加上寄存器dst和ar/m源加上操作码隐含的立即操作数.
一些单操作数指令使用相同的技巧将该reg
字段用作额外的操作码位,但没有立即操作.例如neg r/m32
,not r/m32
,inc r/m32
,或shl
/ shr
由一个隐式1(不是由移位/循环编码cl
或立即).所以很遗憾你不能复制和转移(直到BMI2).
还有一些特殊的情况下的编码,以改善代码密度,如单字节编码为push rax
/ push rdx
该包装reg
领域入操作码字节的低3位.在16/32位模式下,inc
/ dec
任何寄存器的单字节编码.但在64位模式下,这些0x4?
代码用作REX前缀来扩展reg
和r/m
字段以提供16个架构寄存器.
也有部分或全部隐含的操作数的指令,比如movsb
从中拷贝字节[rsi]
到[rdi]
,并可与被用rep
前缀重复rcx
多次.
或mul ecx
做edx:eax = eax * ecx
.一个显式源操作数,一个隐式源和2个隐式目标寄存器. div
/ idiv
是相似的.
具有至少1个显式reg/mem操作数的指令对其使用ModR/M编码,但具有零显式操作数(如movsb
或cdq
)的指令没有ModR/M字节.他们只有操作码.有些指令没有操作数可言,甚至没有隐含的,喜欢mfence
.
立即操作数无法通过ModR/M发出信号,只能由操作码本身发出信号,因此push imm32
或者push imm8
拥有自己的操作码.隐式目标(内存位于[rsp]
,RSP本身正在更新rsp-=8
).
LEA是一种变通方法,让86 3操作数移位和相加,喜欢lea eax, [rdi + rdi*2 + 123]
做eax = rdi*3 + 123
在一个指令.请参阅在非地址/指针的值上使用LEA? 目标寄存器在ModR/M reg
字段中编码,两个源寄存器在寻址模式下编码.(涉及SIB字节,其存在由ModR/M字节使用编码来发信号,否则将表示base = RSP).
VEX前缀(与AVX一起引入)提供类似bzhi eax, [rsi], edx
或的3操作数指令vaddps ymm0, ymm1, [rsi]
. (对于许多指令,第二个源是可选内存的源,但对于某些来说它是第一个源.)
第3个操作数以2或3字节VEX前缀编码.
有一些3操作数非VEX指令,例如SSE4.1变量混合,例如vpblendvb xmm1, xmm2/m128, <XMM0>
XMM0是使用该寄存器的隐式操作数.
的AVX版本使得非破坏性(具有在VEX前缀编码的单独的目标),并且使所述共混物控制操作数显式的(在1字节立即数的高4位编码). 这给了我们一个带有4个显式操作数的指令VPBLENDVB xmm1, xmm2, xmm3/m128, xmm4
.
x86非常狂野并且已经扩展了很多次,但是典型的整数代码主要使用2操作数指令,并且为了保存指令而投入了大量的LEA.
归档时间: |
|
查看次数: |
95 次 |
最近记录: |