我有这个汇编代码,我应该将其转换为二进制形式的机器代码:
.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地址?)
答案 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(如果后面的指令将是该指令的地址。)