Featured image of post Addressing Modes of MIPS Architecture

Addressing Modes of MIPS Architecture

Explains MIPS addressing modes using lui + addiu and $gp, with examples and binary search patterns.

Abstract

  • MIPS instructions are 4 bytes in size.

  • However, memory addresses are also 4 bytes long, which means a single instruction is not enough to directly load a full memory address.

  • In MIPS, memory addresses are typically computed using two approaches:
    the lui + addiu method and the $gp method.


Addressing Methods in MIPS

The lui + addiu Method

  • This method uses two instructions—lui and addiu—to construct a memory address.

  • Example instructions:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    # MIPS big endian
    lui   $a0, 0x0000  3c 04 00 00
    addiu $a0, 0x0000  24 84 00 00
    
    # MIPS little endian
    lui   $a0, 0x0000  00 00 04 3c
    addiu $a0, 0x0000  00 00 84 24
    
    # lui   : loads the operand shifted left by 16 bits
    # addiu : adds the operand (immediate addition, unsigned)
    

    assem-lui-addiu.png

  • The $a0 register stores the first function argument.

  • From $a0 to $a3, a total of four argument registers exist, and all of them can be used for address calculation.

  • To check whether a program uses the lui + addiu method, you can search for the corresponding instruction patterns in the binary:

    1
    2
    3
    4
    5
    
    # MIPS big endian
    hexdump -C firm.bin | grep "3c 04 .. .. 24 84 .. .." --colour
    
    # MIPS little endian
    hexdump -C firm.bin | grep ".. .. 04 3c .. .. 84 24" --colour
    

    hexdump-lui-addui.png


The $gp Method

  • $gp is the Global Pointer register.

  • Within a program, all $gp references point to the same memory region.

  • This region contains addresses that are referenced by the program.

  • To compute the global pointer, instructions like the following are used:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    # MIPS big endian
    lui   $gp, 0x0000  3c 1c 00 00
    addiu $gp, 0x0000  27 9c 00 00
    addu  $gp, $t9     03 09 e0 21
    
    # MIPS little endian
    lui   $gp, 0x0000  00 00 1c 3c
    addiu $gp, 0x0000  00 00 9c 27
    addu  $gp, $t9     21 e0 09 03
    
    # lui   : loads the operand shifted left by 16 bits
    # addiu : adds the operand (immediate addition, unsigned)
    # addu  : adds register values
    

    assem-gp.png

  • The $t9 register holds the current function entry point address.

  • Memory accesses are then computed as an offset from $gp.
    assem-gp-2.png

  • To check whether a program uses the $gp method, search for the $gp initialization sequence:

    1
    2
    3
    4
    5
    
    # MIPS big endian
    hexdump -C firm.bin | grep "3c 1c .. .. 27 9c .. .." --colour
    
    # MIPS little endian
    hexdump -C firm.bin | grep ".. .. 1c 3c .. .. 9c 27" --colour
    

    hexdump-gp.png

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy