分支机器代码

时间:2014-02-28 01:56:18

标签: assembly branch mips memory-address machine-code

我对分支指令如何转换为机器代码感到困惑。我在我的书中读到,如果相等指令是分支指令,那么分支的格式如下:

操作码reg1 reg2地址+偏移量    6 5 5 16

在我的教科书中,有一个问题,我被显示一个程序,我被告知加载在0x4321ABC8,看起来像这样:

L1:   sw   $t0,3000($t1)

  addi $s1,$t1,-6

  beq  $t0,$t1,L1

如您所见,第3行代码是相同的分支。

我正在尝试将此程序转换为二进制(或十六进制)。 在分支上,如果是相同的指令,我不明白究竟是什么,我应该进入地址+偏移字段。

首先我认为答案是......

基地址(0x4321ABC8), 加上程序计数器所在基数指令数的4倍(4 * 2 = 8),
然后减去四个偏移量,这将是原始基地址0x4321ABC8。

这个问题是0x4321ABC8是一个太大而不适合指令的16位偏移空间的数字。

那么我认为答案只是包括偏移量(这将是-8),但如果是这种情况,我不知道为什么书中的问题会费心去告诉我程序加载到0x4321ABC8。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

实际上,偏移量被编码为字数(或指令,如果您愿意),因此您不需要乘以字大小(4个字节)。此外,此偏移量相对于已更新的PC,即以下指令的地址。因此,您的偏移量为-3

但这不是整个故事。 MIPS 确实有分支延迟槽,但它们通常对程序员隐藏。如果可以在不改变代码含义的情况下执行此操作,汇编程序可能会尝试填充这些内容。如果将示例提供给实际汇编程序(在本例中为gas),它会将addi $s1,$t1,-6移动到分支的延迟槽中,因为该条目的结果未在条件中使用:

00000000 <L1>:
   0:   ad280bb8        sw      t0,3000(t1)
   4:   1109fffe        beq     t0,t1,0 <L1>
   8:   2131fffa        addi    s1,t1,-6

在此交换顺序中,编码的偏移量为-2,您也可以从fffe值中看到。

PS:如果你正在使用SPIM,请注意它已知道偏移编码的一个一个问题。也就是说,它使用当前指令的地址而不是下一个指令的地址。

PS#2:仅仅因为他们给你一些额外的信息,并不意味着你必须使用它。这是混淆贫困学生的常见伎俩;)