Regardless of the optimization level, a pointer loaded with an immediate value at the assembly level is loaded a slightly different value, being corrected using a fixed offset when dereferenced.
E.g
int test(){
int *tmp = (int*)0x30000004;
tmp[0]++;
return tmp[1];
}
Compiled with mips-linux-gnu-gcc-8 -O3 -nostdlib test.c -c
generates the following assembly:
Disassembly of section .text:
00000000 <test>:
0: 3c033000 lui v1,0x3000
4: 8c640004 lw a0,4(v1)
8: 8c620008 lw v0,8(v1)
c: 24840001 addiu a0,a0,1
10: 03e00008 jr ra
14: ac640004 sw a0,4(v1)
As you can see the $v1
register is loaded with 0x30000000
and then the offsets are all shifted by +4
.
Why does GCC do this?
Is it possible to deactivate?
The end goal would be to get something like this:
Disassembly of section .text:
00000000 <test>:
li v1,0x30000004
lw a0,0(v1)
lw v0,4(v1)
addiu a0,a0,1
jr ra
sw a0,0(v1)