'逃避操作码'是什么意思?

问题描述 投票:1回答:1

intel software developers manual volumen 2A chapter 2.1.2

用于通用和SIMD指令的双字节操作码格式包括以下之一:

  • 转义操作码字节0FH作为主操作码和第二操作码字节。
  • 强制前缀(66H,F2H或F3H),转义操作码字节和第二个操作码字节(与前一个子弹相同)。

什么是'逃避操作码',它的目的是什么?

assembly encoding x86 opcode machine-code
1个回答
6
投票

一般来说,“转义”代码是修改下一个字节/符号含义的代码,而不是自己的含义。

例如,在ASCII键盘输入中(例如在Linux终端上),alt +字母通常作为转义+字母发送。 (在ASCII ESC character is 0x1b,所以如果我运行hd(hexdump)并输入alt + x,我从那个修改过的击键中得到1b 78

或者在双引号C字符串中,n只是一个简单的字母。但\n意味着不同的东西:它是一个换行符,仍然是一个单一字符(在编译器处理转义序列之后)。反斜杠正在逃避n所以它意味着别的东西。


x86机器代码有许多单字节操作码(如00 ADD r/m8, r8),但有些字节值(如0F)是多字节操作码的第一个字节,而不是自己的整个操作码。

通过使用一个单字节操作码(0f)来扩展256个可能的操作码(加上ModRM字节的/ r字段中的过载)的编码空间,以提供另外256个2字节操作码。

例如,0F AF is IMUL r32, r/m320F B6 is movzx r32, r/m8。这些常用指令是在原始8086之后引入的,并且没有留下编码空间来为它们提供单字节操作码。 (或英特尔正在为将来的转义序列保存它。)


66这样的强制性前缀类似于扩展编码空间以允许编码更多不同操作码的想法,使用在其他上下文中具有不同含义的字节而不是仅仅是转义字节(当出现在操作码的开头时)。

这些字节是操作数大小,REP/REPE, and REPNE前缀,当与那些前缀有意义的操作码一起使用时。但是对于某些指令,这些前缀没有意义:操作码已经意味着单个操作数大小,并且它不是字符串指令。 (注意,地址大小前缀和段覆盖前缀可以应用于具有显式内存操作数的任何指令,因此不用作强制性前缀。也不是lock。)

像MMX 0F FC paddb mm0, mm1/m64这样的指令已经具有固定的SIMD操作数大小。这些前缀都不会对它有意义。英特尔选择(用于SSE2)制作XMM版本66 0F FC PADDB xmm1, xmm2/m128,为MMX编码添加操作数大小前缀。

同样,F3 0F 59 MULSS xmm1,xmm2/m32mulps +一个REP前缀。

英特尔已将rep用作某些非SIMD指令的强制前缀。例如pauserep noptzcntrep bsf(这很有趣,因为他们在有/无BMI1的CPU上做同样的事情,除非输入为零)。这允许向后兼容,因为通常CPU忽略它们不理解为应用的REP前缀。

(故意使用不适用的REP前缀作为填充不是未来的证明,因为编码可以在未来的CPU中获得一些意义。但是当新旧意义都已知时,英特尔通常会保证所有旧CPU都将rep nop解码为nop ,可以安全地在spinloops中使用pause,而无需检查CPUID功能位。)

© www.soinside.com 2019 - 2024. All rights reserved.