1.24. STRUCTURES
29 sw $a1, 0x28+arg_4($sp)
30 sw $a2, 0x28+arg_8($sp)
31 sw $a3, 0x28+arg_C($sp)
32 la $a0, ($LC0 & 0xFFFF) # "a=%d; b=%d; c=%d; d=%d\n"
33 move $a1, $t0
34 move $a2, $v1
35 jalr $t9
36 move $a3, $v0 ; branch delay slot
37 lw $ra, 0x28+var_4($sp)
38 or $at, $zero ; load delay slot, NOP
39 jr $ra
40 addiu $sp, 0x28 ; branch delay slot
41
42 $LC0: .ascii "a=%d; b=%d; c=%d; d=%d\n"<0>
Structure fields come in registers $A0..$A3 and then get reshuffled into $A1..$A3 forprintf(), while 4th
field (from $A3) is passed via local stack usingSW.
But there are two SRA (“Shift Word Right Arithmetic”) instructions, which preparecharfields. Why?
MIPSisabig-endianarchitecturebydefault2.8onpage464,andtheDebianLinuxweworkinisbig-endian
as well.
So when byte variables are stored in 32-bit structure slots, they occupy the high 31..24 bits.
And when acharvariable needs to be extended into a 32-bit value, it must be shifted right by 24 bits.
charis a signed type, so an arithmetical shift is used here instead of logical.
One more word
Passing a structure as a function argument (instead of a passing pointer to structure) is the same as
passing all structure fields one by one.
If the structure fields are packed by default, the f() function can be rewritten as:
void f(char a, int b, char c, int d)
{
printf ("a=%d; b=%d; c=%d; d=%d\n", a, b, c, d);
};
And that leads to the same code.
1.24.5 Nested structures
Now what about situations when one structure is defined inside of another?
#include <stdio.h>
struct inner_struct
{
int a;
int b;
};
struct outer_struct
{
char a;
int b;
struct inner_struct c;
char d;
int e;
};
void f(struct outer_struct s)
{
printf ("a=%d; b=%d; c.a=%d; c.b=%d; d=%d; e=%d\n",
s.a, s.b, s.c.a, s.c.b, s.d, s.e);