属性:pack_mode
プラグマは、割り当て中にデータ構造がどのようにパックされるかを定義します。属性はデータ構造の上に挿入する必要があり、構造全体のパッキングに影響します。
構文:
{attribute 'pack_mode' := ' <pack mode value> '}
挿入場所:データ構造の宣言の上
<pack mode value>
<パックモード値> | 関連する梱包方法 | 説明 |
---|---|---|
0 | 整列 | すべての変数はバイトアドレスに割り当てられます。メモリギャップはありません。 |
1 | 1バイト整列 | |
2 | 2バイト整列 | . がある
|
4 | 4バイト整列 | . がある
|
8 | 8バイト整列 | . がある
|
ヒント
構造によっては、各モードのメモリマッピングに違いがない場合もあります。たとえば、構造体のメモリ分散は、 {attribute 'pack mode' := '4'}
プラグマは次のプラグマに対応できます。 {attribute 'pack mode' := '8'}
。
ヒント
構造体の配列
構造体が配列で結合されている場合、次の構造体が整列されるように、構造体の最後にバイトが追加されます。
重要
の場合 互換性レイアウト シンボル構成でオプションが選択されていると同時に、属性が選択されている 'pack_mode'
コードでが使用されている場合、意図しないメモリの不整合が原因で問題が発生する可能性があります。
例1
{attribute 'pack_mode' := '1'} TYPE myStruct: STRUCT Enable: BOOL; Counter: INT; MaxSize: BOOL; MaxSizeReached: BOOL; END_STRUCT END_TYPE
データ型の変数のメモリ範囲 myStruct
「整列」して割り当てられます。そのコンポーネントのストレージアドレスの場合 Enable
は 0x0100
たとえば、コンポーネント Counter
住所で続く 0x0101
、 MaxSize
住所で 0x0103
と MaxSizeReached
住所で 0x0104
。の場合 'pack_mode':=2
、 Counter
になります 0x0102
、 MaxSize
で 0x0104
と MaxSizeReached
で 0x0105
。
例2
STRUCT Var1 : BOOL := 16#01; Var2 : BYTE := 16#11; Var3 : WORD := 16#22; Var4 : BYTE := 16#44; Var5 : DWORD := 16#88776655; Var6 : BYTE := 16#99; Var7 : BYTE := 16#AA; Var8 : DWORD := 16#AA; END_TYPE
pack_mode = 8 | pack_mode = 0 | pack_mode = 1 | pack_mode = 2 | pack_mode = 4 | ||||||
---|---|---|---|---|---|---|---|---|---|---|
変数 | 価値 | 変数 | 価値 | 変数 | 価値 | 変数 | 価値 | 変数 | 価値 | |
0 |
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
|
|
3 | … |
| … |
| … |
| … |
| … |
|
4 |
|
|
|
|
|
|
|
|
|
|
5 |
|
|
|
| ||||||
6 | … |
| … |
|
|
| ||||
7 | … |
| … |
| … |
| ||||
8 |
|
| … |
| … |
| … |
|
|
|
9 | … |
|
|
|
|
| … |
| … |
|
10 | … |
|
|
|
|
|
|
| … |
|
11 | … |
|
|
|
|
|
|
| … |
|
12 |
|
| … |
| … |
|
|
|
|
|
13 |
|
| … |
| … |
| … |
|
|
|
14 | … |
| … |
| … |
| ||||
15 | … |
| ||||||||
16 |
|
|
|
| ||||||
17 | … |
| … |
| ||||||
18 | … |
| … |
| ||||||
19 | … |
| … |
| ||||||
20 | ||||||||||
21 | ||||||||||
22 | ||||||||||
23 | ||||||||||
24 | ||||||||||
25 | ||||||||||
26 | ||||||||||
27 | ||||||||||
28 | ||||||||||
29 | ||||||||||
30 | ||||||||||
31 |
例3
STRUCT Var1 : BYTE := 16#01; Var2 : LWORD := 16#11; Var3 : BYTE := 16#22; Var4 : BYTE := 16#44; Var5 : DWORD := 16#88776655; Var6 : BYTE := 16#99; Var7 : BYTE := 16#AA; Var8 : WORD := 16#AA; END_TYPE
pack_mode = 8 | pack_mode = 0 | pack_mode = 1 | pack_mode = 2 | pack_mode = 4 | ||||||
---|---|---|---|---|---|---|---|---|---|---|
変数 | 価値 | 変数 | 価値 | 変数 | 価値 | 変数 | 価値 | 変数 | 価値 | |
0 |
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
| ||||||
2 | … |
| … |
|
|
| ||||
3 | … |
| … |
| … |
| ||||
4 | … |
| … |
| … |
|
|
| ||
5 | … |
| … |
| … |
| … |
| ||
6 | … |
| … |
| … |
| … |
| ||
7 | … |
| … |
| … |
| … |
| ||
8 |
|
| … |
| … |
| … |
| … |
|
9 | … |
|
|
|
|
| … |
| … |
|
10 | … |
|
|
|
|
|
|
| … |
|
11 | … |
|
|
|
|
|
|
| … |
|
12 | … |
| … |
| … |
|
|
|
|
|
13 | … |
| … |
| … |
| … |
|
|
|
14 | … |
| … |
| … |
| … |
| ||
15 | … |
|
|
|
|
| … |
| ||
16 |
|
|
|
|
|
|
|
|
|
|
17 |
|
|
|
|
|
|
|
| … |
|
18 | … |
| … |
|
|
| … |
| ||
19 | … |
| … |
| ||||||
20 |
|
|
|
| ||||||
21 | … |
|
|
| ||||||
22 | … |
|
|
| ||||||
23 | … |
| … |
| ||||||
24 |
|
| ||||||||
25 |
|
| ||||||||
26 |
|
| ||||||||
27 | … |
| ||||||||
28 | ||||||||||
29 | ||||||||||
30 | ||||||||||
31 |
なしの行動 'pack-mode'
もしも 'pack-mode'
が使用されていない場合、コンパイラは通常、デバイスの説明に応じてパックモード4または8を使用します。いずれの場合も、メモリアクセスを実行できるように、プロセッサにとって特に有益なパックモードが使用されます。これは、データの自然な配置または自然な配置とも呼ばれます
使用時の悪影響 'pack-mode'
アラインされていないメモリアクセスは、属性を使用した結果である可能性があります 'pack_mode'
。これは、たとえば、サイズが4バイトのデータ型が4で割り切れないアドレスに配置されることを意味します。通常、32ビットシステムでは、32ビットデータ型は次のように読み書きできます。シングルメモリアクセス。一部のプラットフォーム、たとえばARMプラットフォームでは、これはこの値がメモリ内で整列されている場合にのみ可能です。他のプラットフォームでは、アクセスは可能ですが、実行速度がはるかに遅くなる可能性があります。
{attribute 'pack_mode':=1} TYPE DUT STRUCT by1 : BYTE; dw1 : DWORD; END_STRUCT END_TYPE
ARMプラットフォームでは、値 dw1
1回のアクセスで読み取ることはできません。この要素に直接アクセスしようとすると、ARMプロセッサは例外をスローします。
仮定:次の読み取りアクセスが実行されます。 dwTest := dut1.dw1;
このアクセスのために DWORD dw1
、各バイトが個別に読み取られ、シフトされ、分離されるため、4つのメモリアクセスが必要です。フローは、次の例と多少同じです。 DWORD
4バイトの配列から生成されます。
dwHelp := bytes[0]; dwResult := dwHelp; dwHelp := bytes[1]; dwHelp := SHL(dwHelp, 8); dwResult := dwResult OR dwHelp; dwHelp := bytes[2]; dwHelp := SHL(dwHelp, 16); dwResult := dwResult OR dwHelp; dwHelp := bytes[3]; dwHelp := SHL(dwHelp, 24); dwResult := dwResult OR dwHelp;
明らかに、この種のアクセスは、 DWORD
、メモリ内で適切に配置されます。
pdw := ADR(dut1.dw1); dwTest := pdw^;
ただし、この種のメンバーがポインターを使用してアクセスされる場合、コンパイラーは例のアクセスを生成しません。これは、次のコードがARMプラットフォームで例外になることを意味します。
pdw := ADR(dut1.dw1); dwTest := pdw^;
したがって、パフォーマンス上の理由から、自然に整列されていない構造での作業は避けてください。
パックされた構造には、アンパックされた構造が含まれていてはなりません。