Reputation: 71
lets say if i have
.data
prompt1 .asciiz " string1 "
prompt2 .asciiz " String2 "
.text
main:
addi $v0, $0, 4
lui $a0, 0x1000 #this will give me prompt1
So how do i get to prompt2 and what the working behind it? Best if someone could explain it to me using lui and what the advantage or disadvantage vs using la.
Upvotes: 0
Views: 510
Reputation: 62048
To get an address of a variable into a register you typically write this in MIPS assembly:
la $v0, prompt1
To then load its contents into a register you'd do (assuming you're interested in its first byte):
lb $v1, 0($v0)
And to store (to its first byte):
sb $v1, 0($v0)
Now, that la
thing in la $v0, prompt1
is a macro instruction, meaning there's no such real instruction in the CPU. It typically expands into the following two instructions that do exist in the CPU:
lui $v0, %hi(prompt1)
addu $v0, %lo(prompt1)
The first loads bits 31 through 16 of $v0 with bits 31 through 16 of the address of prompt1. The second loads the rest of the bits, 15 through 0.
So, if you look at the above la followed by lb closely enough, you'll see there are three actual instructions behind them:
lui $v0, %hi(prompt1)
addu $v0, %lo(prompt1)
lb $v1, 0($v0)
But you can do better:
lui $v0, %hi(prompt1)
lb $v1, %lo(prompt1)($v0)
The same, of course, can be done with storing.
So, if you need to access a variable just once, you can use the two-instruction sequences (first of the two being lui
) to read or write it. If you need the actual address for something (e.g. if you want to pass it to, say, printf
), then you need to use la
. If you need both, use la
and keep the address in the register for as long as you need/can. So, there you go, the advantages and disadvantages.
Upvotes: 1
Reputation: 4922
I'm not familiar with MIPS, but those are labels and not functions. You should be able to refer to their locations with the la
instruction (Load address) like such: la $a0, .prompt1
or .prompt2
if that was what you were after.
lui
is Load Upper Immediate: it loads the immediate 16 bit value in to the upper 16 bits of a register. Thus lui %a0 0x1000
is in C register x = 0x1000 << 16 /* 0x10000000 */
. So why does this exist? Why not just a "load immediate" instruction like this: li %a0 0x10000000
? Well, MIPS has 32 bit instructions and the first 16 of those are needed to encode the instruction name and the register to be used, so we can only use 16 bit immediate values.
To get a 32 bit value in to a register, such as (in C again): register x = 0x10002000
we need two instructions, first load the upper bits (lui %a0 0x1000
) and then the lower bits (addi %a0, 0x2000). So if .prompt1 is at address 0x1000000 and you can get there using
lui` then to get to .prompt2 you may need to add a 16 bit immediate value.
Upvotes: 1