0

I am learning MIPS assembly and was wondering how I load and store a memory address in MIPS.

For example lets say I have this C code:

int i;

i = 0xFFFF0000;

And then how would I store an address? For example I want to store the value of i to address 0x2000A000.

2 Answers 2

2
LUI V0, 0xFFFF         << load 0xffff0000 into v0
LUI A0, 0x2000
ORI A0, A0, 0xA000     << load address to A0
SW V0, (A0)            << Stores V0 at address held in A0

Alternatively if your assembler supports macro opcodes (I think almost all do these days)

LUI V0, 0xFFFF
LI A0, 0x2000A0000
SW V0, (A0) 

Be careful that A0 is WORD/32bit aligned.

Sign up to request clarification or add additional context in comments.

2 Comments

With lui $a0, 0x2001 / sw $v0, 0xffffa000, you can skip the ORI. It's non-trivial because bit 16 of the address has its sign-bit set, so SW sign-extends but ORI zero-extends, and you have to account for the difference. (+1 in the upper 16 to offset the 0xffff = -1 that sign-extension produces).
Good catch, It's been a long time since I've actually written MIPS.
2

Let the compiler show you:

#define SOME_ADDRESS (*((volatile unsigned int *) 0x2000A000  ))
void fun ( void )
{
    SOME_ADDRESS = 0xFFFF0000;
}

compile and disassemble

Disassembly of section .text:

00000000 <fun>:
   0:   3c022000    lui $2,0x2000
   4:   3442a000    ori $2,$2,0xa000
   8:   3c03ffff    lui $3,0xffff
   c:   ac430000    sw  $3,0($2)
  10:   03e00008    jr  $31
  14:   00000000    nop

As pointed out in the comments there is a missed optimization, but that is not the point of this answer. 1) Learn asm 2) learn to optimize the asm...down the road. Using the compiler you will get to see some of those optimizations. But not in this case.

#define SOME_ADDRESS (*((volatile unsigned int *) 0x20004000  ))
void fun ( void )
{
    SOME_ADDRESS = 0xFFFF0000;
}

00000000 <fun>:
   0:   3c022000    lui $2,0x2000
   4:   3c03ffff    lui $3,0xffff
   8:   ac434000    sw  $3,16384($2)
   c:   03e00008    jr  $31
  10:   00000000    nop

Yes it was built for mips32 to get this -march=mips1 and -march=mips32r6 produce the same code. as commented.

6 Comments

That's an unfortunate missed-optimization (using ORI instead of the immediate in sw, see my comment on the other answer). Which compiler did you use? And BTW, godbolt.org has MIPS GCC installed, and clang -target mips also works with any of the clang versions it has installed. hmm, it seems GCC and clang both have that missed optimization, and your code is probably from gcc. godbolt.org/z/r1p5AS clang fills the branch-delay slot with the sw.
Hmm, that's probably only valid for MIPS32; with MIPS64 that would carry into higher bits of the address, and is may why gcc doesn't implement it. But -march=mips32r6 (32-bit only) or -march=mips1 or mips2 (predating 64-bit MIPS) or whatever should make it valid.
Strangely, using a <0x8000 offset (Say Address = 0x20000004) the GCC version emits a proper offset in the SW according to godbolt.org
point being the OP can use a compiler to start to learn assembly language, optimized or not.
and it needs to be aligned so not sure if that is a word offset or byte, but trivial to test for.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.