This is all related, and I tried to piece it all together as logically as I could, so please bear with me.
I'm really confused as to how to properly address labels. For example, in the following bit of code, "bne" translates to "00010101001001010000000000000001", and the label address of loopend is 0x00000020 (32)
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
loopend:
When I move loopend up, "bne" becomes "00010101001001011111111111111011" and the address of loopend becomes 0x00000008 (8)
.text
la $a0, opOne
lw $a0, 0($a0)
loopend:
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
So from what I understand, in the first bit of code, loopend
is after eight instructions, so its address is 4*8=32=0x00000020. In the second bit of code, loopend
is after two instructions, so its address is 4*2, or 0x00000008.
What I don't understand, however, are the label addresses. Correct me if I am wrong: the label address depends on where the label is in relation to the instruction calling it. So in the first bit of code, loopend
is two lines later than bne
so you do not flip the signs, and its address is "0000000000000001". On the second loopend
comes before bne
so you flip the sign and its address becomes "1111111111111011".
I know you shift the addresses to the left 2 bits, but I'm still pretty confused. Do you only shift left if there are not two 0s at the end, like the second loopend
?
My most pressing question is this: where does 0000000000000001, the address of loopend
, even come from in the first bne machine language translation? I thought that address of label loopend
would be 0000000000100000.
BNE -- Branch on not equal
___________________________________________________________________________
|Description: | Branches if the two registers are not equal |
|_____________|_____________________________________________________________|
|Operation: | if $s != $t advance_pc (offset << 2)); else advance_pc (4); |
|_____________|_____________________________________________________________|
|Syntax: | bne $s, $t, offset |
|_____________|_____________________________________________________________|
|Encoding: | 0001 01ss ssst tttt iiii iiii iiii iiii |
|_____________|_____________________________________________________________|
For the first bne the offset is 1, so 1 << 2 = 4 so you increment the program counter by four bytes. Since the word size is 32 bits the pc is incremented by one instruction
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1 # increment by 1 insruction
loopend: # to here (well the next instruction)
For the second bne the offset is b1111111111111011, sign extended its -5 so -5 << 2 = -20 so you increment the program counter by - 20 bytes or decrement it by 20 bytes. Since the word size is 32 bits the pc is decremented by five instructions
.text
la $a0, opOne
lw $a0, 0($a0)
loopend: #
la $a1, opTwo # 5 to here
lw $a1, 0($a1) # 4 ^
add $t0, $zero, $a0 # 3 |
addi $t1, $zero, 1 # 2 |
bne $t1, $a1, loopend # 1 |
addi $t1, $t1, 1 # decrement by 5 instructions