作为我们大学项目的一部分,我们必须编写一个小型汇编程序。它是一个双程汇编程序。我想知道为什么汇编语言允许在操作码中使用符号,例如在它们实际声明之前(后面的代码中)?我认为必须有这样的理由,因为在我知道的大多数编程语言中,你首先声明一个变量然后使用它。此外,如果在汇编语言中就是这种情况,我认为双通道装配工不需要存在。
答案 0 :(得分:3)
您经常跳转到某个前向位置,或者将一些常量(即某些文字字符串的命名地址)传递给汇编指令。在这两种情况下,都需要在定义之前使用。
举个例子,拿一些非常重要的C代码foo.c
,让你的GCC编译器使用gcc -O -fverbose-asm -S foo.c
为它发出汇编代码,然后查看生成的foo.s
};最好在一些现有的几百行的C源文件上做到这一点(例如来自一些现有的自由软件项目)。
.FORWARD symb
指令来明确声明要向前使用的symb
。但是历史上汇编程序没有这样编写(大多数汇编程序甚至没有任何语法来声明但没有定义符号)。并且在定义符号之前要求每次使用.FORWARD
指令是一种负担:在实践中你需要很多这样的指令。所以最好避免它们。
请注意,一些最近(和更高级别)的编程语言不需要转发声明符号,特别是Go language允许您按名称调用函数而不进行前向声明。
(还有其他原因,为什么汇编程序是两遍的:汇编程序正在生成object files relocation信息)
BTW,每个机器代码程序都有某种循环,因此control flow graph是循环的。如果它不是,你的程序将很快退出(在几分之一秒内)。循环(或它们的等价物,例如递归)是计算机的基础。大多数条件(即C中的if
指令)转换为汇编程序中的 forward 条件跳转。另请阅读halting problem。
请注意,符号(或标签,它们是相同的)在汇编代码中是无类型的。
答案 1 :(得分:2)
当引用或定义符号时,汇编器会在符号表中添加符号。在第一次传递期间,汇编程序对符号类型(大小,位于数据或代码部分,......)进行假设,但不需要知道实际地址。
当符号被定义时,它的值被存储到符号表条目中以供第二遍使用。
有多个通道汇编程序可以减少与影响指令大小的前向引用相关的代码大小。