汇编程序指令bne和br(NIOS II)。他们的偏差如何计算?

时间:2011-10-03 11:29:08

标签: assembly instruction-set nios

我有这个汇编代码,我应该将其转换为二进制形式的机器代码:

        .text
        .align 2
        .global main
        .equ val,0x4712         

main:                           
        movi r16,val
        movi r17,0
loop:   addi r17,r17,1
        subi r16,r16,1 
        bne  r16,r0,loop
stop:   br   stop
.end 

并且我不确定如何解释“b16,r0,循环”和“br停止”。

我的指令集引用说bne指令执行此操作:

if(rA != rB)
then PC ← PC + 4 + σ(IMM16)
else PC ← PC +4

根据我的理解,程序计数器增加4 +偏移或简单地增加4。

但是,就我而言,偏移量/ IMM16值是多少?指令集参考说:

“在指令编码中,IMM16给出的偏移量被视为相对于紧随其后的指令的有符号字节数”。

我对此的解释是IMM16值是到下一个指令地址的“距离”,但我不知道这是否正确。 bne的十六进制地址为0x40010,br为0x40014,这意味着IMM16值为4? (如果rA!= rB,会导致PC跳过0x40014地址?)

1 个答案:

答案 0 :(得分:4)

免责声明:我不完全确定这是什么指令集,因此我将尽力坚持汇编语言通常的情况。

  

if(rA!= rB)然后PC←PC + 4 +σ(IMM16)否则PC←PC +4

     

根据我的理解,程序计数器增加4 +偏移或简单地增加4。

这是对的。记住,在获取指令将程序计数器移动到下一个循环的下一条指令后,CPU基本上总是会PC ← PC + 4。因此,即使NOP也会有PC +=4的有效结果(当指令的长度为4个字节时)。 Wikipedia有更多。

此外,由于IMM16可能是负数,因此您可以向后跳。

  

但是,就我而言,偏移量/ IMM16值是多少?指令集参考说:

     

“在指令编码中,IMM16给出的偏移量被视为相对于紧随其后的指令的有符号字节数”。

     

我对此的解释是IMM16值是到下一个指令地址的“距离”,但我不知道这是否正确。 bne的十六进制地址为0x40010,br为0x40014,这意味着IMM16值为4? (如果rA!= rB,会导致PC跳过0x40014地址?)

IMM16值的距离,但它是rA != rB中要跳转到的指令的距离(以字节为单位)!因此,在这种情况下,您希望立即距离bne之后的指令(因为距离相对于以下指令)到您要跳转到的位置(loop)的距离。在这种情况下(如果我的计算是正确的)address(jump-target) - (address(bne-instruction) + 4) = 0x40008 - (0x40010 + 4) = -12 = ~12 + 1 = 0xfff4 (16-bit)

由于您担心指令编码,请注意应用于立即数的sigma函数。我将采取有根据的猜测,并假设它将立即乘以4,然后指令编码将包含跳转减去1的指令数。这是-12字节可能会被编码为16位有符号值0xfffc = -3,因为我们想要用bne向后跳两条指令,因此从指令返回3条指令 bne

  

如果这是真的,那么我仍然不明白IMM16值有什么,因为没有以下说明。当标签“停止”时,它可能是零? (如果rA!= rB和PC←PC + 4 +σ(IMM16))会产生什么样的结果。

请注意br可能有不同的编码(例如,它可能是绝对偏移,也可能是不同的大小)。我对手头的指令集不太熟悉,但是我可以给出一般的想法:你并没有真正使用下面指令的地址,而是使用当前指令的地址+4(如果后面的指令将是该指令的地址。)