DST
DST

Reputation: 71

Trying to understand .data in mips and how to call the functions

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

Answers (2)

Alexey Frunze
Alexey Frunze

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

dave
dave

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 usinglui` then to get to .prompt2 you may need to add a 16 bit immediate value.

Upvotes: 1

Related Questions