【发布时间】:2019-02-22 15:20:41
【问题描述】:
我仍在尝试开发 MIPS 汇编器作为我的任务的一部分。我得到了这些输入和输出文件。
main: lw $a0, 0($t0)
begin: addi $t0, $zero, 0 # beginning
addi $t1, $zero, 1
loop: slt $t2, $a0, $t1 # top of loop
bne $t2, $zero, finish
add $t0, $t0, $t1
addi $t1, $t1, 2
j loop # bottom of loop
finish: add $v0, $t0, $zero
输出的机器码如下:
10001101000001000000000000000000
00100000000010000000000000000000
00100000000010010000000000000001
00000000100010010101000000101010
00010101010000000000000000001000
00000001000010010100000000100000
00100001001010010000000000000010
00001000000000000000000000000011
00000001000000000001000000100000
我注意到代表指令“j循环”的机器代码是
00001000000000000000000000000011
根据 J 型指令格式,最后 26 位将代表目标地址。我从上面写的二进制代码中注意到,这条跳转指令的目标地址(基本上是“循环”的地址)是 00000000000000000000000011,即 3。
我开发了我的程序版本,但它为“循环”检索到的目标地址比这大得多。
我想知道是否有任何方法可以将程序计数器初始化为 0 或任何其他方法,以便获得与输出文件中给定的目标地址相同的目标地址。程序计数器究竟是如何工作的?它会为每一行代码自增吗?
请指教。谢谢!
【问题讨论】:
-
是的,cpu运行代码时会自动递增。由于您正在编写汇编程序,因此您需要维护它的副本。它只是当前指令的地址。你可以初始化任何东西。不涉及魔法。正如我在您的另一个问题中已经说过的那样,地址被移动了 2,因此在您的情况下它实际上是
0x0c。 -
感谢您的回答。所以,地址总是移动了两位,对吧?但是我究竟该如何初始化它......?是否像为某个变量分配零一样简单?我认为情况并非如此......?
-
将机器代码加载到 RAM 并初始化 PC 以指向起始地址不是汇编程序的工作。在一个完整的操作系统中,通常汇编器产生一个“目标代码”文件,在所有跳转指令上都有注释,称为“重定位记录”,它告诉下一个处理阶段,“链接”,调整地址以匹配哪里代码实际上将被放置在内存中。这不是一个很好记录的过程,我唯一的建议是一整本书,约翰·莱文的 Linkers and Loaders。
-
你的汇编器大概有一个变量来维护指令的地址。您需要它来解析标签。将该变量初始化为零,并为每条指令将其递增 4,如果您支持指令,请执行任何适当的操作。
-
@Jester 澄清一下……那个变量是我自己定义的,对吧?例如,我将其定义为
start_counter,然后基本上只为读取的文件中的每条指令将其增加 4?
标签: assembly compiler-construction mips machine-code