2012-05-20 53 views
2

我有一个家庭作业的问题。计算抵消

我有一个BNE指令在0x88888888,我需要告诉什么是合法的跳转范围。

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

  • 从0x8888888 - 4 * 2
  • 为0x88888888 + 4 *(2 -1)

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

+0

你忘了告诉我们你正在使用的指令集。不同的CPU有不同的可用指令集。 –

+0

我们没有告诉任何有关这件事,它可以连接到我们使用的程序? spim模拟器和modelsim? – boaz

+1

是的,SPIM是MIPS指令集的模拟器。我不知道任何细节,但已添加标签到您的问题。希望有人来了解详情。 –

回答

2

查找的指令引用,显示了指令编码如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字节。最大反向分支是0x8000时符号扩展是0xFFFF8000指令,在是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指令执行之后的下一条指令(产生很多意义,流水线或不是通常情况下,pc至少在下一条指令执行时会执行)当你用pc执行数学计算时,pc已经完成了这一步)。这可以通过其他三个分支来验证。 0x2058表示分支一个指令头如果不相等,这意味着PC是0x205C,一个在前。 0xFFFD,反转并加1 = 2 + 1 = 3,所以向后移动三个并达到0x2030,你需要在0x203C,一个在编码指令之前。 0xFFFB 4 + 1 = 5,5个指令返回,这意味着你从0x2044开始,指令后面的分支用0xFFFB编码。

其他指令集并不那么简单。 Arm非常简单,无论是手臂还是拇指模式,都假定在包含指令开始的地址前面有两条指令,所以在拇指模式下为4字节,手臂模式为8字节。即使是主要是32位指令的thumb2,来自程序员角度的程序计数器也是2个指令。

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

+0

感谢所有的explainig,但仍然有些东西我不明白,为什么你在9行做2位偏移? – boaz

+0

向左移2与4相同。每条指令有4个字节,所以要从指令单位转换为字节单位,将指令数乘以4得到字节数。同样,除以四(算术右移)从字节到指令数目。 –

+0

好的,我想我明白了。谢谢 – boaz

0

This SPIM reference说:

分支指令使用符号的16位偏移字段;因此他们可以向后跳转指令(而不是字节)或向指令跳转2 -1。

因为说明似乎总是4个字节宽,所以你的推理看起来是正确的,但你已经交换了标志。

最大后向分支(朝向较低地址)是由2个指令组成的,即32767个指令或131068个字节,因此您可以达到0x88888888 - 131068 = 8886888c

同样,最大前移分支会带您到0x88888888 + 131072 = 0x888a8888