13

Can someone explain me how does lui works, what does "4097" stand for, what does adding 8 to $t0 mean?

.data        0x10010000
    blank:   .asciiz " "  # 4097
    newline: .asciiz "\n" # 4097 + 2

    #input_start
    Alength: .word 13
    Aarray:  .word 130, 202, 30, 4440, 530, 532, 33, 204, 8, 524, 8933, 92, 10
    #input_end

.text
    lui $t0, 4097
    ori $a0, $t0, 8  # address of A[]
    lw  $a1, 4($t0)  # load length
Benjamin H Boruff
  • 2,620
  • 3
  • 16
  • 20
das_tnr
  • 151
  • 1
  • 2
  • 9

4 Answers4

32

4097 = 1001 hex

so, the first instruction puts 0x10010000 into register t0. lui is "load upper immediate", with "upper" meaning the upper 16 bits, and "immediate" meaning that you are giving it a literal value (4097). 4097 as an "upper" value becomes 0x10010000.

ori is "or immediate", with 8 being the immediate value, so the resulting address in a0 is 0x10010008, which is the address where Aarray lives.

The final instruction lw is "load word" which loads from the memory address in t0 (which at this point is still just 0x10010000) plus 4 bytes (the 4 is an offset from t0 and results in an address where ALength lives) 4 bytes of data into a1.

Jim Buck
  • 20,482
  • 11
  • 57
  • 74
13

lui $t0, 4097 is the load upper immediate instruction. The immediate value(4097) is shifted left 16 bits and stored in the $t0 register. The lower 16 bits are zeroes.

Johnny Rocket
  • 1,394
  • 3
  • 17
  • 25
2

This is "doing it manually" to generate static addresses, as a workaround for the MARS assembler lacking %hi(symbol) and %lo(symbol) to get the linker to fill in the 4097 (0x1001) from the high half of the address of Alength and Aarray, and the 4 and 8 from the low half of those addresses.

This code assumes that MARS will put the .data section at 0x10010000, like it says on the line with the .data directive.

The two strings happen to add up to 4 bytes total, so the word values are already word-aligned. This code leaves out a .align directive, even though it would have ended up being zero bytes (until you add another string and your word load breaks).


If you compile this C on the Godbolt compiler explorer:

int x = 1;               // with no initializer it goes in the .bss as  .space 4
int foo() { return x; }

MIPS gcc5.4 -O3 gives you this asm (some noise is stripped away):

foo():
    lui     $2,%hi(x)
    lw      $2,%lo(x)($2)
    j       $31
    nop              # IDK why it didn't put the load in the branch-delay slot; clang does

 .data
 .p2align 2          # actually gcc uses .align 2 but I disambiguated
x:
    .word   1

$2 is $v0, the return value in the standard MIPS calling convention.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
1

Just wanted to add a more accessible explanation of lui $t0, 4097:

  • 4097 in decimal is equal to 1000000000001 in binary
  • lui loads the value in the first 16 bits of the register

So lui $t0, 4097 will store 10000000000010000000000000000 in $t0 which is equal to 268500992 in decimal

Atralb
  • 724
  • 2
  • 8
  • 17