4

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?)

keyser
  • 18,829
  • 16
  • 59
  • 101
  • Your hex-values for bne and br don't seem to be correct. At least they make no sense if I compare them to the NIOS-II instruction set manual. Could you please add the disassembly of your program to your question, so we see the correct values? – Nils Pipenbrinck Oct 03 '11 at 11:46
  • @NilsPipenbrinck I haven't compiled this program. I'm only interpreting the given text version. I received the hexadecimal addresses in the assignment. I left out that the starting address is 0x40000 though. Maybe you're just misinterpreting me when I'm saying "the hex address for bne is...", cause I'm simply stating that this address is given in a column to the right of the instruction. Not that this is the rightmost bit values given in the instruction set. – keyser Oct 03 '11 at 12:14

1 Answers1

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.

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.

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 of PC +=4 (when instructions are 4 bytes in length). Wikipedia has more.

Also since IMM16 can be negative you can jump backwards.

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?)

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 following bne (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 with bne and thus 3 instructions back from the instruction following bne.

If that's true, then I still don't understand what IMM16-value br has since there are no following instructions. Maybe it's zero when the label is "stop"? (or what bne would result in if rA != rB and PC ← PC + 4 + σ(IMM16)).

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).

Community
  • 1
  • 1
user786653
  • 29,780
  • 4
  • 43
  • 53
  • 1
    Thanks for your answer. It was very helpful. I've completely solved this now, and you were correct in every way. And my sigma function seems to be multiplying by 1 sínce my IMM16-value has to be word-aligned. Cheers! – keyser Oct 05 '11 at 18:57