assemblymipsgnu-assemblermips32instruction-encoding

Why LI becomes LBU opcode after MIPS assembler


I'm trying to assemble code for MIPS R2000 (MIPS I ISA).

I'm using LI pseudo instruction to initiate a register. After running the assembler on the following code:

li $v1, 1

The binary .text ends up containing:

24030001

But according to https://www.cs.gordon.edu/courses/cs311/handouts-2015/MIPS%20ISA.pdf, 0x24 is the LBU opcode (Load Byte Unsigned), which makes no sense, since LBU meant for loading bytes from the RAM.

Those are the commands I'm running on Ubuntu:

mips-linux-gnu-as -mips1 -march=r2000 -o out.o code.asm
mips-linux-gnu-objcopy --dump-section .text=out.shellcode out.o

Does someone know why it's happening? Is it a bug or some clever implementation?


Solution

  • The opcode is the top 6 bits only so it's not at the bottom of the byte. It will not appear in the hex dump directly. 0x24 = 0010 0100 the top 6 bits are 001001 = 0x09 which is addiu. li $v1, 1 is emitted as addiu $v1, $0, 1. Since integer division by 4 is equivalent to shifting right by two bits you can also do that instead of performing the binary conversion but make sure you use hex properly.