x86标准是否包含助记符或仅定义操作码?
如果不包括它们,那么对于不同的汇编程序是否还有另一个标准?
答案 0 :(得分:10)
助记符没有标准化,并且不同的汇编程序使用不同的助记符。一些例子:
callPythonScript
,b
,w
和l
应用于所有助记符,以指示操作数的大小。英特尔风格的汇编程序通常使用关键字q
,byte
,word
和dword
qword
,cbtw
,cwtl
和cltq
,而Intel样式的汇编器可识别与cqto
,{{ 1}},cbw
和cwd
cdq
和cqo
,其中movz??
是Intel样式的汇编器称为movs??
,??
和{的两个大小后缀。 {1}} movzx
识别为movsx
,而其他人也将movsxd
识别为该指令的变体。63 /r
被称为movsxd
。
答案 1 :(得分:3)
不幸的是,实际上并没有一个书面的“ x86标准”能够定义CPU必须满足的最低要求才能成为x86。
英特尔的文档非常接近 “ x86标准”,但是在某些情况下,它提供的保证要比现代AMD CPU强大。例如英特尔保证1/2/4/8字节加载或从/到可缓存内存的原子存储,且对齐方式不得超出缓存行边界。但是AMD只保证不跨越8字节边界的可缓存加载/存储。
Why is integer assignment on a naturally aligned variable atomic on x86?引用了Intel的手册,显示所有保证均以“ Intel486处理器(及以后的较新处理器)”作为保证。没有提供适用于所有 x86 CPU(或更重要的是所有x86-64 CPU)的基准。我认为实际上x86(包括x86-64之前的版本)的实际共享基准是1字节,因为8088。
因此,要在现代x86-64 CPU上运行的软件不能假定8字节加载/存储具有原子性,除非它们实际对齐。我认为我们都可以同意原子性保证是成为现代多核x86 CPU的重要组成部分。即使在单个内核上,未缓存的MMIO访问的原子性也很重要。现代英特尔和AMD对此表示同意,但英特尔再次仅以“奔腾及其后继处理器”的形式对其进行记录。暗指“后来的 Intel 处理器”。
这就是说,英特尔文档确实为每个操作码定义了助记符,并注册了名称。在所有这些方面,AMD的文档均与英特尔的文档保持一致。
请参阅Intel's x86 Software Development Manuals的第2卷。可以在https://www.felixcloutier.com/x86/index.html和https://github.com/HJLebbink/asm-dude/wiki上找到仅按指令手册条目的HTML摘录(没有解释符号和指令格式的部分),其他地方的旧版本格式也不同。>
正如@fuz解释的那样,大多数汇编程序都选择遵循此标准,但这不是必需的。重要的部分是二进制兼容性,而不是asm源兼容性。
英特尔必须为指令分配名称,以便它可以在其其余手册中用英语谈论它们,而不是因为它们需要世界上每个人都使用相同的asm语法。
我不确定英特尔的手册是否甚至完整定义了完整的asm语法(例如,如何在寻址模式下指示段覆盖前缀)。
在某些情况下,他们所做的工作远远超出了描述哪个机器代码做什么的范围,例如在字符串指令lods / stos / movs / cmps / scas(可能还有ins / outs)中,您会在Intel的vol.2手册中找到类似这样的段落:
在汇编代码级别,此指令的两种形式允许使用:“显式操作数”形式和“无操作数”形式。显式操作数形式(使用MOVS助记符指定)允许显式指定源和目标操作数。此处,源和目标操作数应该是分别指示源值和目标的大小和位置的符号。提供此显式操作数形式是为了允许文档;但是,请注意,此表格提供的文档可能会产生误导。也就是说,源和目标操作数符号必须指定操作数(字节,单词或双字)的正确的类型(大小),但不必指定正确的位置< / strong>。源操作数和目标操作数的位置始终由DS:(E)SI和ES:(E)DI寄存器指定,必须在执行移动字符串指令之前正确加载它们。
(突出显示(an HTML extract of)原始PDF)
某些“ Intel语法”汇编程序(例如NASM)会忽略此设置,仅允许将大小为movs
的{{1}}用作助记符,例如movsb
。 NASM还具有用于指示段覆盖前缀(例如fs lodsd
)的语法,该前缀不需要操作数,因此,这完全避免了使用指示错误的内存操作数但仍会汇编的操作数的可能性。
(字符串指令仅使用隐式内存操作数,而不使用ModR / M寻址模式。)
NASM: parser: instruction expected rep movs
Convert Instruction in assembly code lods and stos so NASM can compile
是的,Intel-syntax汇编有多种形式,更不用说AT&T这样的语法了。
AT&T有意对某些指令使用不同的助记符,甚至将一些共享Intel语法助记符的操作码拆分为单独的助记符,例如movzb
表示movzx
,带有字节源,以及movzw
表示词源版本。 (通常也使用大小后缀,例如movzbl
,但也可以根据需要从32位目标寄存器中推断出l
。)
与两个寄存器操作数a syntax design bug we're stuck with一起使用时,AT&T语法无意中将fsubr
与fsub
交换。 (幸运的是,x87总体上已经过时了。)