Question

I found this exam question that I have to tell how the beq instruction is coded in machine code.

This is the code:

loop:  addu    $8, $9, $10
    addiu   $8, $8, 0x00FF7A01
    beq    $8, $0, loop

Although my first question would be 0x1100FFFD the correct answer is 0x1100FFFB. I believe that this is because 0x00FF7A01 is bigger than 16 bit and addiu $8, $8, 0x00FF7A01 must be "decompiled" in more than one instruction.

So here are my questions.

Q1 - In what is addiu $8, $8, 0x00FF7A01 decomplided?

Q2 - And what if the immediate field on the beq instruction was bigger than 16 bits? Must I have to use jumps?

Was it helpful?

Solution

Not sure how the assembler works here, but to allow addiu $8, $8, 0x00FF7A01 be assembled correctly, multiple instructions are necessary, as you have expected. Normally, addiu is a valid instruction that takes in 16-bit integer only.

The instruction addiu $8, $8, 0x00FF7A01 is minimally rewritten as these 3 instructions:

addiu $8, $8, 0x7A01
lui $11, 0x00FF // Assume nothing significant is stored in $11
addiu $8, $8, $11

Since there is now difference of 5 instructions from branch instruction, we need to put -5 in the immediate field of beq, which is 0xFFFB (detailed explanation here).

If the destination is outside the range of -217 to 217-1 bytes (or to the power of 15 in term of number of instructions), then jump instruction must be used.

OTHER TIPS

Q1)

For your first question, you mean assemble, not decompiled.

 addiu   $8, $8, 0x00FF7A01

Your assessment was correct, since the immediate value was bigger than what we can store in a single instruction, we would need to use multiple instructions. The assembler will use the $at (Assembler Temporary, which is $1) register for that.

lui    $at, 0x00FF
ori    $at, $at, 0x7A01
addu   $t0, $t0, $at

Q2)

The branch instructions use what is called PC-relative addressing - the immediate value does not contain the actual address by rather the word offset. Since we know the instruction must be word (2^2) aligned, the low 2 bits are always zero. The actual address will be calculated on the fly by shifting the offset left by 2 and adding it to the address of the instruction following the branch. The final value will be our PC-relative effective address. So we actually have 17 bits to play with (technically 18, but the offset is signed).

When the offset exceeds that range, the assembler will use far branches - a branch followed by a jump.

beq $x, $y, label

will become

      beq   $x, $y, temp
      # ...
      j tskip
temp:
      j tlabel
      # ...
      # ...
tskip:
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top