Home > Back-end >  How do you move data at one memory location to another in RISCV programming?
How do you move data at one memory location to another in RISCV programming?

Time:06-18

I am new to RISC-V programming and assembly programming in general.

I want to move a 32 bit word from an address in memory, say 0x04000000, to another address say 0x00000190.

Do I have to load the data to a GPR first (using lw?), then store to the new address (e.g. sw?)? Or is there a more direct way?

Is there anything wrong with these instructions:

lw x8, 0(x67108864)
sw x8, 192(x0)

thanks

CodePudding user response:

You won't be able to encode that load instruction on RISC V, as it only allows for 12-bits of immediate/offset, and, it must follow the regular base displacement form usually written as disp(reg).  Some assemblers will accept immediates of that size by expanding that line into multiple machine code instructions.

There are two additional instructions that can help form larger immediates:

  • LUI — Load Upper Immediate provides for 20 bits of immediate that when combined in sequence with an I-Type instruction (which offer 12 bits of immediate) allows for a 32-bit immediate in 2 instructions.

  • AUIPC — Add upper immediate to the PC also provides for 20 bits of immediate and adds the immediate to the PC to form PC-relative addressing capability.

Additionally we can use shifts and other instructions as well.

Even if that load were encodable, the x is a typo, since you want x4000000, aka 67,108,86410 (not x67108864).


That store instruction will encode is ok.

CodePudding user response:

I have had/issues with the volatile pointer thing, but it works here. You can have the tools show you how to do it...sometimes...

#define ONE (*((volatile unsigned int *)0x04000000))
#define TWO (*((volatile unsigned int *)0x00000100))
void fun ( void )
{
    TWO=ONE;
}

which, for me, gives

00000000 <fun>:
   0:   040007b7            lui x15,0x4000
   4:   439c                lw  x15,0(x15)
   6:   10f02023            sw  x15,256(x0) # 100 <fun 0x100>
   a:   8082                ret

you can often just use the li pseudo instruction and the assembler will pick the right combination of lui, addi, for you.

  • Related