正如我在问题中
所问的,汇编代码编译过程中的 pass 是什么,谢谢解释
2 回答
为了生成目标文件,汇编器需要做两件事,将每个指令助记符翻译成指令字节,add eax, ds:[eax]
例如0x0000
.
其中一些很容易做到,因为所有信息都包含在指令中。但是,有些指令引用了指令之外的元素,例如:
- 跳跃,有一个跳跃目标
- 指向数据访问中的内存位置的指针
如果已经看到跳转目标或内存位置,则没有问题。但是,程序集并不限制您访问已看到的位置(例如 C,它只允许您使用在文件中较早的位置定义的标识符),因此可能存在标识符不可用的情况还知道。例如:
cmp eax, 0
jz skip_this
add eax, edx
skip_this:
mov ecx, eax
在这个例子中,不知道什么skip_this
时候jz
遇到,所以汇编器不知道放什么地址。
为了构建目标文件,汇编器一次处理一行汇编文件。它翻译它可以翻译的内容,并跟踪它仍然不知道的内容。到此阶段结束时,所有标识符都已遇到。
当汇编器完成这个阶段时,它再次处理汇编文件并填补空白。
现在,为了回答您的问题,从头到尾处理整个源文件的每个阶段都称为pass。
“通过”的意思正是——通过源头的“通过”。回到打孔卡时代,您必须按照汇编器/编译器所需的次数将卡组通过。
许多旧的汇编程序是“两次通过”,这意味着“甲板”被输入一次以计算代码偏移量,第二次生成代码(当然,这是在卡片上打孔)。
当然,使用更现代的设置,您不会注意到汇编程序是否有 10 次通过(性能较差除外),因为它完全不在磁盘上,并且在通过之间没有用户交互。
还有“阶段”,编译器(不仅仅是汇编器)可能是“两阶段”或“三阶段”或更多,这取决于代码从源代码到最终对象输出的转换次数。