A.6.3 構造体宣言のメンバオフセット

構造体メンバは、構造体アドレスにオフセットを加算してアクセスします。オフセットを小さくするとサイズが有利になるので、よく使用するメンバを先頭に宣言するようにしてください。

もっとも効果的なのは、signed char, unsigned char型で先頭から32byte未満, short, unsigned short型で先頭から64byte未満, int, unsigned, long, unsigned long型で先頭から128byte未満です。

【使用例】

以下の例は、構造体のオフセットによってコードが変わる例を示します。

改善前ソースコード

struct str {
         long L1[8];
         char C1;
};
struct str STR1;
char x;
void func()
{
         x = STR1.C1;
}

改善前アセンブリ展開コード

_func: 
       MOV.L #_STR1,R4
       MOVU.B 20H[R4],R5
       MOV.L #_x,R4
       MOV.B R5,[R4]
       RTS

改善後ソースコード

struct str {
         char C1;
         long L1[8];
};
struct str STR1;
char x;
void func()
{
         x = STR1.C1;
}

改善後アセンブリ展開コード

__func:
        MOV.L #_STR1,R4
        MOVU.B [R4],R5
        MOV.L #_x,R4
        MOV.B R5,[R4]
        RTS

■注意事項

構造体を定義する際には、境界調整数を意識してメンバの宣言をおこなってください。

構造体の境界調整数は構造体内の最も大きな境界調整値に合わせられ、構造体のサイズは境界調整数の倍数となります。その為、構造体の末尾が構造体自身の境界調整数と合わない場合に、次の境界調整を保証するために生成される、未使用領域もサイズに含めてしまいます。

改善前ソースコード

/* 最大メンバがint型の為、境界調整数は4 */
struct str {
         char C1; /* 1byte + 境界調整分 3byte */
         long L1; /* 4byte */
         char C2; /* 1byte */
         char C3; /* 1byte */
         char C4; /* 1byte + 境界調整分 1byte */
}STR1;

改善前strサイズ

       .SECTION B,DATA,ALIGN=4
       .glb _STR1
_STR1:                     ; static: STR1
       .blkl 3 

改善後ソースコード

/* 最大メンバがint型の為、境界調整数は4 */
struct str {
         char C1; /* 1byte */
         char C2; /* 1byte */
         char C3; /* 1byte */
         char C4; /* 1byte */
         long L1; /* 4byte */
}STR1;

改善後strサイズ

       .SECTION B,DATA,ALIGN=4
       .glb _STR1
_STR1:                     ; static: STR1
       .blkl 2