Hi,
In MIPS (and similarly for other RISC architectures) to load an absolute address of an object
requires a two instruction sequence: one instruction to load the high part of the object's address,
and one instruction to load the low part of the object's address. Typically the result from the
calculation of the high part of the address will only be used by one instruction to load
the low part of the address. However, in certain situations (for example when loading or
storing double word values) the result of computing the high part of the address can be
used by multiple instructions to load the low parts of an address at different offsets. Lets
show this with an example C program.
However, if we add the packed attribute to the h structure, the fields of the structure will
not be naturally aligned and we can break the previous condition. Lets explain this in more
detail with the following C program.
struct __attribute__((packed))
{
short s;
unsigned long long l;
} h;
void foo (void)
{
h.l = 0;
}
When this is compiled for MIPS it produces the following assembly:
lui $2,%hi(h)
addiu $4,$2,%lo(h+2)
addiu $3,$2,%lo(h+6)
swl $0,3($4)
swr $0,%lo(h+2)($2)
swl $0,3($3)
jr $31
swr $0,%lo(h+6)($2)
...
.globl h
.section .bss,"aw",@nobits
.align 2
.type h, @object
.size h, 10
h:
.space 10
There are two things to highlight here. Firstly the alignment of the h structure has decreased
from 8 bytes to 4 bytes. Secondly we have a low part calculation which adds an offset of 6
to the address of the h structure which is greater than its alignment.
When the MIPS linker resolves a HI relocation (i.e. %hi(h)) it finds the next LO
relocation (i.e. %lo(h+2)) in the relocation table and using the information from both
of these relocations it computes the object's address and extracts its high part. Then, when the
MIPS linker resolves a LO relocation it adds the offset to the object's address and then extracts
the low part.
Lets assume that object h has an address of 0x80007ffc. When the MIPS linker resolves the value
of the HI relocation for object h, it will also use the value of the LO relocation for object h
with an offset of 2. The high part value is therefore: