x86 cpu有什么样的地址指令?

Jol*_*151 2 cpu x86 computer-science instruction-set cpu-architecture

我学到了一个地址,两个地址和三个地址指令,但是现在我想知道x86使用什么样的地址指令?

Pet*_*des 5

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个字段:

  • r/m操作数的2位模式(寄存器直接reg,寄存器间接[reg],[reg + disp8],[reg+disp32]).具有位移位的模式表示那些字节遵循ModR/M字节.
  • 3位r/m字段(用于该操作数的寄存器,或用于存储器寻址模式的转义码,表示在ModRM之后有一个Scale/Index/Base字节,可以编码r/m的缩放索引寻址模式操作数).请参阅rbp不允许作为SIB基础?有关特殊情况/转义码的详细信息.
  • 3位寄存器字段,始终是寄存器.

大多数指令至少有2种编码,reg/memory destination或reg/memory source.如果你想要的操作数都是寄存器,你可以使用操作码,add r/m32, r32或者add r32, r/m32.

通用指令还有其他操作码用于即时源代码形式,但通常它们使用regModR/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前缀来扩展regr/m字段以提供16个架构寄存器.


也有部分或全部隐含的操作数的指令,比如movsb从中拷贝字节[rsi][rdi],并可与被用rep前缀重复rcx多次.

mul ecxedx:eax = eax * ecx.一个显式源操作数,一个隐式源和2个隐式目标寄存器. div/ idiv是相似的.

具有至少1个显式reg/mem操作数的指令对其使用ModR/M编码,但具有零显式操作数(如movsbcdq)的指令没有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 次

最近记录:

6 年,10 月 前