Assembly 什么是';转义操作码';什么意思?
在报纸上说 通用和SIMD指令的双字节操作码格式 由以下内容之一组成:Assembly 什么是';转义操作码';什么意思?,assembly,encoding,x86,opcode,machine-code,Assembly,Encoding,X86,Opcode,Machine Code,在报纸上说 通用和SIMD指令的双字节操作码格式 由以下内容之一组成: 转义操作码字节0FH作为主操作码和第二个操作码字节 强制前缀(66H、F2H或F3H)、转义操作码字节和第二个操作码字节(与前面的项目符号相同) 什么是“转义操作码”及其目的是什么?通常,“转义”代码是修改下一个字节/符号含义的代码,而不是其本身的含义 例如,在ASCII键盘输入中(例如在Linux终端上),alt+字母通常作为escape+字母发送。(在这里,如果我运行hd(hextump)并在其中键入alt+x,我将
- 转义操作码字节0FH作为主操作码和第二个操作码字节
- 强制前缀(66H、F2H或F3H)、转义操作码字节和第二个操作码字节(与前面的项目符号相同)
hd
(hextump)并在其中键入alt+x,我将从修改过的按键中获得1b 78
)
或者在双引号的C字符串中,n
只是一个普通的字母。但是\n
的意思不同:它是一个换行符,仍然是一个字符(在编译器处理转义序列之后)。反斜杠转义的是n
,因此它意味着其他东西
x86机器码有许多单字节操作码(如),但有些字节值(如
0F
)是多字节操作码的第一个字节,而不是一个完整的操作码
通过使用一个单字节操作码(0f
)来提供另256个2字节操作码,从256个可能的操作码(加上ModRM字节/r字段中的重载)扩展了编码空间
例如,和。这些通用指令是在最初的8086之后引入的,没有剩余的编码空间来为它们提供单字节操作码(或者Intel将其保存以备将来转义序列使用)
像
66
这样的强制前缀是一个类似的想法,它扩展了编码空间,允许编码更多不同的操作码,使用在其他上下文中具有不同含义的字节,而不仅仅是转义字节(出现在操作码开头时)
这些字节是操作数大小,当与操作码一起使用时,这些前缀是有意义的。但对于某些指令,这些前缀没有意义:操作码已经暗示了单个操作数大小,而不是字符串指令。(请注意,地址大小前缀和段覆盖前缀可以应用于任何具有显式内存操作数的指令,因此不作为强制前缀使用。lock
)
像MMX这样的指令已经有固定的SIMD操作数大小。这些前缀对它来说都没有意义。英特尔选择(对于SSE2)使XMM版本66 0F FC PADDB xmm1,xmm2/m128
,在MMX编码中添加操作数大小前缀
类似地,F3 0F 59 MULSS xmm1,xmm2/m32
是mulps
+一个REP前缀
英特尔使用了rep
作为一些非SIMD指令的强制前缀。例如pause
是rep nop
,tzcnt
是rep bsf
(这很有趣,因为它们在有/没有BMI1的CPU上做同样的事情,除非输入为零)。这允许向后兼容,因为通常CPU会忽略它们在应用时不理解的REP前缀
(不过,故意使用不适用的REP前缀作为填充并不是未来的证明,因为这种编码在未来的CPU中可能会有某种意义。但是,当新旧含义都已知时,Intel通常会保证所有旧CPU都将REP nop
解码为nop
,这样就可以安全地在spinlo中使用pause
不检查CPUID特征位的操作。)通常,“转义”代码修改下一个字节/符号的含义,而不是其本身的含义
例如,在ASCII键盘输入中(例如,在Linux终端上),alt+字母通常作为escape+字母发送。(因此,如果我运行hd
(hextump)并在其中键入alt+x,我将从一次修改的击键中获得1b 78
)
或者在双引号的C字符串中,n
只是一个普通的字母。但是\n
的意思不同:它是一个换行符,仍然是一个字符(在编译器处理转义序列之后)。反斜杠转义的是n
,因此它意味着其他东西
x86机器码有许多单字节操作码(如),但有些字节值(如
0F
)是多字节操作码的第一个字节,而不是一个完整的操作码
通过使用一个单字节操作码(0f
)来提供另256个2字节操作码,从256个可能的操作码(加上ModRM字节/r字段中的重载)扩展了编码空间
例如,和。这些通用指令是在最初的8086之后引入的,没有剩余的编码空间来为它们提供单字节操作码(或者Intel将其保存以备将来转义序列使用)
像
66
这样的强制前缀是一个类似的想法,它扩展了编码空间,允许编码更多不同的操作码,使用在其他上下文中具有不同含义的字节,而不仅仅是转义字节(出现在操作码开头时)
这些字节是操作数大小,当与操作码一起使用时,这些前缀是有意义的。但对于某些指令,这些前缀没有意义:操作码已经暗示了单个操作数大小,而不是字符串指令。(请注意,地址大小前缀和段覆盖前缀可以应用于任何具有显式内存操作数的指令,因此不作为强制前缀使用。lock
)
像MMX这样的指令已经有固定的SIMD操作数大小。这些前缀对它来说都没有意义。Intel选择(对于SSE2)使XMM版本66 0F FC PADDB xmm1,xmm2/m128
,添加了