汇编指令 bne 和 br (NIOS II)。它们的偏移量是如何计算的?
我有这个汇编代码,我应该将其翻译成二进制形式的机器代码:
.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
并且我不确定如何解释“bne r16,r0,loop”和“br stop”。
我的指令集参考说 bne 指令执行以下操作:
if(rA != rB)
then PC ← PC + 4 + σ(IMM16)
else PC ← PC +4
据我所知,程序计数器增加 4 + 偏移量或简单地增加 4。
但是,就我而言,偏移量/IMM16 值是多少?指令集参考说:
“在指令编码中,IMM16 给出的偏移量被视为相对于紧随 bne 的指令的有符号字节数”。
我对此的解释是 IMM16 值是到下一个指令地址的“距离”,但我不知道这是否正确。 bne 的十六进制地址是 0x40010,br 的十六进制地址是 0x40014,所以这意味着 IMM16 值是 4? (如果 rA != rB,这会导致 PC 跳过 0x40014 地址?)
I have this assembler code, which I'm supposed to translate into machine code in binary form:
.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
and I'm not sure how "bne r16,r0,loop" and "br stop" is interpreted.
My instruction set reference says that the bne instruction does this:
if(rA != rB)
then PC ← PC + 4 + σ(IMM16)
else PC ← PC +4
which, as I understand it, is the program counter being incremented by 4 + offset or simply by 4.
But, in my case, what is the offset/IMM16 value? The instruction set reference says:
"In the instruction encoding, the offset given by IMM16 is treated as a signed number of bytes relative to the instruction immediately following bne".
My interpretation of this is that the IMM16 value is the "distance" to the next instruction address, but I have no idea if this is correct. The hex-address for bne is 0x40010 and 0x40014 for br, so this would mean that the IMM16 value is 4? (which would result in PC jumping past the 0x40014 address if rA != rB?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
免责声明:我不完全确定这是什么指令集,因此我将尝试坚持汇编语言通常的情况。
这是正确的。请记住,在获取一条指令以将程序计数器移至下一个周期的下一条指令后,CPU 基本上总是会执行
PC ← PC + 4
,这可能会有所帮助。因此,即使是 NOP 也会产生PC +=4
的有效结果(当指令长度为 4 字节时)。 维基百科有更多内容。另外,由于 IMM16 可能为负,因此您可以向后跳转。
IMM16 值是距离,但它是到您要跳转到的指令的距离(以字节为单位),以防万一
rA!= rB
!因此,在这种情况下,您希望立即数是从bne
后面的指令(因为该距离相对于后面的指令)到您要跳转到的位置(loop
)的距离代码>)。在这种情况下(如果我的计算正确)address(jump-target) - (address(bne-instruction) + 4) = 0x40008 - (0x40010 + 4) = -12 = ~12 + 1 = 0xfff4 (16 -位)
。当您担心指令编码时,请小心注意应用于立即数的 sigma 函数。我将进行有根据的猜测,并假设它将立即数乘以 4,然后指令编码将包含要跳转的指令数减一。也就是说,-12 字节可能会被编码为 16 位有符号值
0xfffc = -3
,因为我们希望使用bne
向后跳转两条指令,从而向后跳转 3 条指令来自以下bne
指令。请注意,
br
可能具有不同的编码(例如,它可能是绝对偏移量,也可能是不同的大小)。我对手头的指令集不太熟悉,但我可以给出总体思路:您并没有真正使用以下指令的地址,而是使用当前指令的地址 + 4 (如果后面有一条指令,则该指令就是该指令的地址)。Disclaimer: I'm not completely sure what instruction set this is, so I'll try to stick to what is usually the case for assembly languages.
This is correct. It might be helpful to keep in mind that the CPU will basically always do
PC ← PC + 4
after fetching an instruction to move the program counter to the following instruction for the next cycle. So even a NOP would have the effective result ofPC +=4
(when instructions are 4 bytes in length). Wikipedia has more.Also since IMM16 can be negative you can jump backwards.
The IMM16 value is the distance, but it's the distance (in bytes) to the instruction you want to jump to in case
rA != rB
! So in this case you want the immediate to be the distance from the instruction followingbne
(because the distance is relative to the following instruction) to the place you want to jump to (loop
). In this case (if my calculations are correct)address(jump-target) - (address(bne-instruction) + 4) = 0x40008 - (0x40010 + 4) = -12 = ~12 + 1 = 0xfff4 (16-bit)
.As you're worried about instruction encoding be careful to note the sigma function applied to the immediate. I'll take an educated guess and assume that it multiplies the immediate by 4, and the instruction encoding would then contain the number of instructions to jump minus one. That is -12 bytes would probably be encoded as the 16-bit signed value
0xfffc = -3
, since we want to jump two instructions back withbne
and thus 3 instructions back from the instruction followingbne
.Be aware that
br
might have a different encoding (it could be e.g. be an absolute offset or it could be a different size). I'm not familiar enough with the instruction set at hand to know, but I can give the general idea: You're not really using the address of the following instruction, rather you're using the address of the current instruction + 4 (which if an instruction follows would be the address of that instruction).