assembly - 计算偏移量

标签 assembly mips spim

我有一个家庭作业问题。

我在 0x88888888 处有一条 BNE 指令,我需要知道合法的跳转范围是多少。

我的理论是偏移量告诉我我可以走:

  • 从 0x8888888 - 4 * 215
  • 至 0x88888888 + 4 * (215-1)

我真的不明白为什么以及如何工作,有人可以解释一下吗?

最佳答案

查找显示指令编码的指令引用,例如 http://en.wikipedia.org/wiki/MIPS_architecture

000100ss sssttttt CCCCCCCC CCCCCCCC

s 和 t 保存正在比较的寄存器,5 位,每个给出寄存器 0 - 31。低16位是以指令为单位的偏移量。

(对于 mips)从程序员的角度来看,假设程序计数器领先 1 条指令,4 个字节。因此,对于地址 0x88888888,请使用地址 0x88888888+4 = 0x8888888C 进行计算。

指令编码使用二进制补码,因此最大前向分支是 0x7FFF 指令,即 0x7FFF<<2 = 0x1FFFC 字节。当符号扩展为 0xFFFF8000 条指令时,最大向后分支为 0x8000,以字节为单位,即 0xFFFF8000<<2 = 0xFFFE000

0x8888888C + 0x0001FFC = 0x888A8888
0x8888888C + 0xFFFE000 = 0x88868888

通过对工作汇编器生成的工作代码进行反汇编,可以非常简单地找出程序计数器的调整。 (加上指令引用至少足以看到您必须使用的位数)。

00002030 <back>:
    2034:
    2038:   1443fffd    bne v0,v1,2030 <back>
    203c:   00000000    nop
    2040:   1443fffb    bne v0,v1,2030 <back>
    2044:   00000000    nop
    2048:   1443fff9    bne v0,v1,2030 <back>
    204c:   00000000    nop
    2050:   14430003    bne v0,v1,2060 <fore>
    2054:   00000000    nop
    2058:   14430001    bne v0,v1,2060 <fore>
    205c:   00000000    nop

00002060 <fore>:

0x1443FFFD 和 0x1443FFFB 相距 8 个字节,并且相距两条指令。指令中偏移量之间的差异为 2,这意味着编码是以指令/字为单位,而不是以字节或半字为单位。前向引用比较容易做到,首先0x2060 - 0x2050是0x10字节,也就是4条指令。偏移量是 3 条指令,0x2060 减去 3 条指令是 0x2054 执行 bne 的指令之后的下一条指令(很有意义,无论是否流水线,PC 通常至少在执行时至少在下一条指令上,并且当您使用电脑执行数学运算时,电脑已经完成了该操作)。这可以通过其他三个分支来验证。 0x2058 表示如果不相等则跳转到一个指令头,这意味着 pc 是 0x205C,领先一位。 0xFFFD,反转并添加 1 = 2+1 = 3,因此要向后移动 3 并到达 0x2030,您需要位于 0x203C,即编码指令前一位。 0xFFFB 4+1 = 5,向后5个指令,这意味着您从0x2044开始,即用0xFFFB编码的分支之后的指令。

其他指令集就没那么简单了。 Arm相当简单,arm和thumb模式都假设从包含指令开头的地址开始有两条指令,因此在thumb模式下为4字节,arm模式为8字节。即使thumb2主要是32位指令,从程序员的角度来看,程序计数器也领先2条指令。

可变字长指令集,不像arm、mips等那么规则。要么硬件像thumb2那样使用固定规则,尽管预取了实际地址。或者您必须从指令的大小知道程序计数器的位置并使用该引用。请注意,也许这些处理器的第一次切割,程序计数器在执行时就在前面一两个指令处,但是埋在其中许多指令(arm、mips)中的流水线预取地址可能是规则的,但前面更远,或者当你可以通过分支预测进行超标量,取指可以在任何地方,甚至可以接触硬件中的寄存器(好的硬件设计不会在简单读取时修改任何内容,只写入,你不会读取值并自动递增硬件指针,例如,至少)适用于可在许多处理器上使用的 pci(e) 硬件。

关于assembly - 计算偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10672507/

相关文章:

c - MIPS 结构节点

c++ - 将 C++ 代码转换为 SPIM 程序集

assembly - 为什么QtSPIM告诉我 “Label is defined for the second time”?

c++ - Sprite 文件格式

mips - MIPS 流水线处理器项目

c - 了解如何为 MIPS 模拟器设置内存

c - 独立于汇编操作系统的原子比较和交换

c - 当按下输入时禁用/启用中断(时间)

assembly - 一个地址有多少字节?

c - 在 c extern 中引用外部 msp430 程序集 .string