4.2.5.3 BaseReg+Offset Operands
Load and store operations select the memory location using a
BaseReg+Offset operand. For an operand of this type, the effective address is formed by
adding the 32-bit signed offset to the contents of a base register. A PIC32M data sheet
shows this type of operand as Mem[R+offset]
.
#include <xc.h>
.data
.align 4
MY_WORD_DATA:
.word 0x10203040, 0x8090a0b0
.text
.global example
/* Store Word */
example:
la v0, MY_WORD_DATA
lui v1,0x1111
ori v1,v1,0x4432
lui a0,0x5555
ori a0,a0,0x1123
sw v1, 0(v0) /* Mem[GPR[v0]+0] <- GPR[v1] */
sw a0, 4(v0) /* Mem[GPR[v0]+4] <- GPR[a0] */
lw a1, 0(v0) /* GPR[a1] <- Mem[GPR[v0]+0] */
b .
The C compiler supports global-pointer relative (GP-relative) addressing.
Loads and stores to data lying within 32 KB of either side of the address stored in the gp
register (64 KB total) can be performed in a single instruction using the gp register as
the base register. The C compiler's -G
option lets you
change the maximum size of global and static data items that can be addressed in one
instruction instead of two from the default value of 8 bytes, which is large enough to hold
all simple scalar variables.
.align 2
.globl foo
.set nomips32
.ent foo
foo:
.set noreorder
.set nomacro
lw $3,%gp_rel(testval)($28)
addiu $2,$3,1
sw $2,%gp_rel(testval)($28)
j $31
nop
.set macro
.set reorder
.end foo
-G
option. There are a few potential pitfalls to using GP-relative addressing:
- You must take special care when writing assembler code to declare
global (i.e., public or external) data items correctly:
- Writable, initialized data of not more than the number of bytes
specified by the
-G
option must be put explicitly into the.sdata
section, for example:.sdata small: .word 0x12345678
- Global common data must be declared with the correct size, for
example:
.comm small, 4 .comm big, 100
- Small external variables must also be declared correctly, for
example:
.extern smallext, 4
- Writable, initialized data of not more than the number of bytes
specified by the
- If your program has a very large number of small data items or
constants, the C compiler's
-G8
option may still try to push more than 64 KB of data into the ''small'' region; the symptom will be obscure relocation errors (''relocation truncated'') when linking. Fix it by disabling GP-relative addressing with the compiler's-G0
option and/or reducing the space reserved in the small data sections (i.e..sbss
and.sdata)
in your assembly code.