出于学习目的,我正在关注此汇编源代码,并遇到以下几行:
# load a disk extent into high memory
# eax - sector address
# ecx - sector count
# edi - destination
load_extent:
; loading kernel to 1MiB
; move part of kernel to startup_end via bootsector#load and then copy it up
; repeat until all of the kernel is loaded
buffer_size_sectors equ 127
有一些以
#
开头的行似乎是注释。
然后他跟进标签
load_extent:
并添加以;
开头的评论。这是我习惯看到的。
这是故意这样做的,这样人们就不会不小心复制他的代码吗?还是我错过了什么?
我浏览了整个 NASM 文档,并且没有提到哈希是注释字符,但我自己对 NASM v 2.11.08 的实验显示以
#
开头的行被视为注释行。所以它看起来像是 NASM 的非官方功能。文档中仅提到了 ;
字符。
奇怪的是,这行:
xx: # inc ebx
标签后使用哈希的地方将失败,并显示“错误:解析器:预期指令”。
同样来自 NASM 历史变更列表:“#、@、~ 和 c{?} 现在是标签中的有效字符。” 自 1996 年 v0.91 起,因此
xx#yy:
定义了符号标签 xx#yy
。
这使得它在某种程度上与 sh 脚本兼容,并且在为 C 和 NASM 创建混合头文件时可能会被更多地滥用,其中 NASM 将忽略 C 预处理器指令,因此这可能很有用。
但我建议不要使用这个,至少在官方承认这是 NASM 的有意功能,而不是解析器的一些错误之前。
在用完整答案回答这个问题之前,我早期评论中的一些闲聊:
汇编不是单一的编程语言,而是所有机器语言助记符的总称=>没有规则。
每个CPU供应商都有自己的指令集(“ISA”),并且需要特定的汇编器,并且每个汇编器供应商往往会填补官方文档中缺失的空白(这些文档仅描述指令功能,而不是定义编程语言的完整有效语法),因此即使在同一个 CPU 上,您也可以使用方言略有不同的汇编器,一种支持 # 作为注释,另一种则不支持。
在 x86 上,甚至存在语法截然不同的汇编器:AT&T 与 NASM,远远超出了额外的注释开始字符,实际上颠倒了指令操作数的顺序,并对某些指令使用不同的助记符(例如
movzbl
与 movzx
) )等...
对于其他示例:在流行的(大学课程)MIPS 模拟器“MARS”和“SPIM”中,
#
是唯一的注释字符,而不是 ;
,但这在其官方文档中有详细记录(与x86)。
从 NASM 2.16 开始,在行首放置
#
是一项已记录的功能,其中 #
充当 %line
指令的别名:
4.13.1
指令%line
...
为了与其他一些预处理器(包括许多 C 预处理器)的输出兼容,行首的
字符后跟空格也被视为#
指令,但文件名周围的双引号会被处理就像 NASM 反引号一样,带有%line
——解码的转义序列。\
这样做的结果是 NASM 无法在预处理阶段组装有问题的代码,因为这自然不是
%line
指令的有效语法。
--no-line
选项(在版本 2.14.01 中引入),则所有 %line
指令都会被预处理器忽略,从而有效地使 %line
和 #
成为评论开始的标记。因此,如果您有一些为早期版本的 NASM 编写的旧代码,使用 #
进行注释,并且不包含任何其他 %line
指令(最有可能是这种情况),那么将 --no-line
附加到您的 NASM命令是 NASM 2.16+ 的简单修复。
但奇怪的是,我似乎在手册的附录 C 中找不到任何提及此更改的内容。也许它只是被认为不够重要,不足以值得在这里指出?老实说我对此表示怀疑,但我真的想不出更好的理由。