MIPS Instruction Decoding

2.1k views Asked by At

I'm trying to understand how to decode MIPS binary instructions.

I compiled a hello world program in C on a Debian MIPS system with gcc and objdump shows me that the first instruction in the .text section is:

600: 03e00025 move zero,ra

I don't understand how it determines that this is the MOVE instruction.

03e00025 is 00000011111000000000000000100101 in binary. If I understand correctly the first 6 bits here are the opcode, which in this case is all 0, meaning it's an R-type instruction, so we have to look at the last 6 bits, which is 100101. Looking at the MIPS Instruction Set Manual it looks like this should be the OR instruction. I can't even find MOVE in that manual.

Googling for this I found that apparently there are "pseudo" instructions in the assembly, and supposedly move $t, $s expands to addiu $t, $s, 0, but if I look in the manual ADDIU has opcode 001001. Another result I found claims it translates to ADD but the last six bits of ADD should be 100000, so that doesn't fit either.

What am I missing?

1

There are 1 answers

2
Peter Cordes On BEST ANSWER

MIPS machine code doesn't have a specific opcode for move, but for the convenience of humans, many assemblers support pseudo-instructions like li, la, and move that assemble to one or more real machine instructions. addiu is a common one.

It would be totally correct for objdump to decode the instruction as or $0, $ra, $0 (according to Jester) to show you how it's actually encoded.

For some purposes it makes sense for a disassembler to decode any of the commonly used ways to copy a register into a move mnemonic. Adding or ORing an immediate 0, or a zero from reading the $zero register, do nothing to the value so it's copied unchanged.

When reading the asm, you normally don't care whether it's or, ori, addiu $0, $ra, 0, or whatever.


Different assemblers might use different implementations for the move pseudo-instruction, or hand-written asm could use any of them. I don't think there are any performance consequences either way. So the details of which machine instruction is used to implement a move depends on the assembler.


I'm not sure what the point of a move with a destination of $zero is. That would be a no-op, because $zero discards writes. (It's the CPU-register equivalent of /dev/zero)