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.
