MIPS label addressing?

Laurence picture Laurence · Apr 29, 2013 · Viewed 12.6k times · Source

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.

Answer

Musa picture Musa · Apr 29, 2013
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