首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x86组装Mnemonic是否标准化?

x86组装Mnemonic是否标准化?
EN

Stack Overflow用户
提问于 2019-01-25 16:56:37
回答 2查看 1.4K关注 0票数 4

x86标准是否包括助记符,还是仅仅定义了操作码?

如果它不包括它们,是否有另一个标准为不同的汇编程序?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-25 17:14:58

助记符不是标准化的,不同的汇编器使用不同的助记符。下面是一些例子:

  • AT&T风格的汇编程序将bwlq后缀应用于所有助记符,以指示操作数大小.Intel风格的汇编程序通常用关键字byteworddwordqword来表示这一点。
  • AT&T风格的汇编程序识别cbtwcwtlcltqcqto,而Intel风格的汇编程序识别与cbwcwdcdqcqo相同的指令。
  • AT&T风格的汇编程序识别movz??movs??,其中??是英特尔风格汇编程序所称的movzxmovsxmovsxd的两个大小后缀。
  • 一些Intel风格的汇编程序只将63 /r识别为movsxd,而另一些则认为movsx是该指令的变体。
  • 计划9风格的汇编程序(如Go中使用的)非常奇怪,并且在很多方面都有差异,例如使用Motorola风格的助记符来进行条件跳转。
  • 历史上,NEC汇编程序为8086的NEC V20克隆提供了几乎完全不同的助记符。例如,int被称为brk
票数 11
EN

Stack Overflow用户

发布于 2019-01-26 05:46:41

遗憾的是,在纸上没有一个“标准”可以定义一个x86.必须满足的所有最低要求。

英特尔的文档非常接近于"x86标准“,但在某些情况下,比在现代AMD上得到的更有力的保证。例如,Intel保证原子性的1/2/4/8字节加载或存储从/到可缓存内存与任何对齐,不跨越缓存线边界。但AMD只为不跨越8字节边界的可缓存加载/存储提供保证。

为什么x86上自然对齐变量的整数赋值是原子的?引用了英特尔的手册,表明所有的保证都是作为"Intel486处理器(以及此后更新的处理器)“来保证的。给定的基线不适用于所有x86 CPU(更重要的是适用于所有x86-64 CPU)。我认为x86的实际共享基线(包括pre-x86-64)是1字节,因为有8088字节。

因此,希望在现代x86-64 CPU上运行的软件不能为8字节加载/存储假定原子性,除非它们实际上对齐。我认为我们都同意原子性保证是成为一个现代多核x86 CPU必不可少的一部分。即使是在单个核上,未实现MMIO访问的原子性也很重要;现代英特尔( Intel )和AMD (AMD)在这一点上达成了一致,但同样,英特尔只是用“奔腾和后来的处理器”来记录它。含蓄地“后来的英特尔处理器”。

说,英特尔的文档确实为每个操作码定义了助记符,并注册了名称。AMD的文档和英特尔在所有这些方面都是一致的。

英特尔的x86软件开发手册的第2卷。在https://www.felixcloutier.com/x86/index.htmlhttps://github.com/HJLebbink/asm-dude/wiki中可以找到每条指令手册条目的HTML摘录(没有解释符号和指令格式的部分),而且其他许多地方的旧版本的格式也不同。

正如@fuz所解释的那样,解释说,大多数汇编程序选择遵循这个标准,但这并不是必需的。的重要部分是二进制兼容性,而不是asm源代码兼容性。

英特尔必须为指令指定名称,这样它才能在其余的手册中用英语谈论它们,而不是因为它们需要世界上的每个人都使用相同的语法。

我不确定Intel的手册甚至完全定义了完整的asm语法(例如,如何在寻址模式中指示分段覆盖前缀)。

在某些情况下,它们确实远远超出了描述机器代码的功能,例如,在字符串指令lods/stos/movs/cmp/scas(可能还有ins/out)中,您可以在Intel的第2卷手册中找到类似的段落:

在程序集代码级别上,允许这种指令的两种形式:“显式-操作数”形式和“无操作数”形式。显式操作数表单(使用movs助记符指定)允许显式指定源操作数和目标操作数。在这里,源操作数和目标操作数应该是分别指示源值和目标的大小和位置的符号。提供这个显式操作数表单是为了允许文档;但是,请注意,此表单提供的文档可能具有误导性。也就是说,源操作数和目标操作数符号必须指定操作数的正确类型(大小)(字节、单词或双单词),但它们不必指定正确的位置。源操作数和目标操作数的位置总是由DS:(E)SI和ES:(E)DI寄存器指定的,在执行移动字符串指令之前必须正确加载这些寄存器。 (高亮显示来自( HTML摘录)的原始PDF)

一些像NASM这样的“Intel语法”汇编程序忽略了这一点,只允许使用大小相同的movs作为助记符的一部分,比如movsb。NASM还具有语法,用于指示不需要操作数的段覆盖前缀(如fs lodsd ),因此这完全避免了使用指示错误内存操作数但仍然组装的操作数的可能性。

(字符串指令只使用隐式内存操作数,而不是ModR/M寻址模式。)

NASM:解析器:预期的指令rep

转换汇编代码lods和stos中的指令,以便NASM能够编译

是的,Intel语法程序集有多种不同的风格,更不用说像AT&T这样的非常不同的语法了。

AT&T故意在某些指令中使用不同的助记符,甚至将一些在英特尔语法中共享助记符的操作码拆分为单独的助记符,比如movzb用于movzx和字节源,movzw用于单词源版本。(通常也带有大小后缀,如movzbl,但如果您愿意,可以从32位目标寄存器推断出l。)

AT&T语法在与两个寄存器操作数(即fsubr )一起使用时无意地将fsubfsub交换。(幸运的是,x87作为一个整体基本上已经过时。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54369684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档