NASM 规范中的哪些位置不允许使用十六进制数的语法 FFFFh?

Lon*_*ner 5 syntax x86 assembly hex nasm

我正在尝试用 ASM 组装一小段代码。此代码将 CX 设置为零,将 AX 设置为 1。我的代码:

mov cx, 0000h
mov ax, ffffh
Run Code Online (Sandbox Code Playgroud)

但我收到这个错误:

$ nasm foo.asm
foo.asm:2: error: symbol `ffffh' not defined
Run Code Online (Sandbox Code Playgroud)

我可以通过编写mov ax, 0ffffh来解决此错误。但为什么不明白ffffh语法呢?NASM 文档中的哪个位置指定了允许使用哪些十六进制语法,不允许使用哪些十六进制语法?

我读了https://nasm.us/doc/nasmdoc3.html#section-3.4.1但找不到任何不允许的内容ffffh语法的内容。我缺少什么?

我也阅读了作为对此问题的评论提供的其他一些类似问题。但它们似乎都没有指出一些权威文档或规范来确认数字必须以数字开头。如果有人可以指出 NASM 文档中的确切摘录或某些规范来证实这一点,那就可以回答这个问题。

Pet*_*des 4

令人惊讶的是,我没有看到明确提及数字文字必须以十进制数字开头的语法规则。在您链接的部分中间接提到,以 $ 符号为前缀的十六进制数字必须在 $ 之后有一个数字而不是字母,但他们没有说“必须仍然”,甚至暗示这始终是必需的。

早些时候,在 3.1 中,他们说标识符必须以字母开头,但并没有说只有标识符才能以字母开头。(因为这不是真的,所以可以注册名称和指令助记符。但不能是数字文字。)


这可能是那些“明显”且众所周知的事情之一(对于开发人员/手册作者而言),以至于他们忘记在手册中的任何地方明确地写下它。

不过,十六进制示例确实显示了这一点,包括0c8h但不包括c8h. 他们确实展示了其他基础中不需要前导零的示例。


一些事情使得以字母字符开头的标记永远不应该被解析为数字文字是“显而易见的”和必要的:

  • AH 到 DH 是寄存器名称,因此不能解析为数字。EH如果是数字文字但DH不是数字文字,那就很奇怪了。(寄存器名称与符号名称(而不是数字)符合相同的模式是正常的。除非您使用 PowerPC,否则 GAS 语法仅对寄存器和立即数使用裸数字;您必须通过指令记住哪些位置。或者使用gcc -mregnames.但这是一个 IBM 架构,所以它当然使用奇怪的约定,比如向后编号。)

  • abcdefgh如果是一个符号名称却是一个数字文字,那就太奇怪了abcdefh(因为如果没有g,它都是有效的十六进制数字和尾随的 h。)

  • 不能使用英语单词(each:如标签/符号名称),出于同样的原因,您不能使用1234:. (我试过; foo.asm:1: error: label or instruction expected at start of line)。这是一个有效的 C 标识符,因此如果不能使用它会很不方便。 $eax允许您将其用作符号名称,但$1234在 NASM 中相当于0x1234,具有$作为十六进制指示符的双重职责,因此如果事物使用数字,则它不会将某些内容变成符号名称。

  • 也许最重要的是,这就是 DOS 的早期 x86 汇编器的工作方式,NASM 从中挑选了其语法的优点。就像 MASM 一样,还有 A86 和 as86 之类的东西。
    在 NASM 的早期,人们从其他汇编器转向 NASM 并且已经知道这条规则。(如何在x86汇编编程中表示十六进制值,例如FFFFFFBB?提到了除NASM之外的一些其他汇编器。)


这些都不能证明手册中的遗漏是合理的,而只是解释它。在 3.4.1 中对措辞进行调整以提及这一点将是一个好主意。