Comments
Description
Transcript
4.アセンブリ言語プログラムおよびクロスソフトとの 関連
4.アセンブリ言語プログラムおよびクロスソフトとの 関連 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 272 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.1 アセンブリ言語プログラムとの関連 SuperH RISC engine C/C++コンパイラは、日立 SuperH RISC engine ファミリ専用の特殊命令までサ ポートしているため、ほとんどのプログラムは C 言語で記述できます。しかし、性能を追及する場 合、鍵になる部分をアセンブリ言語で記述し、C 言語プログラムと接続する必要があります。 本節では、C 言語プログラムとアセンブリ言語プログラムの接続時に注意すべき次の事項につい て概説します。 • 外部名の相互参照方法 • 関数呼び出しのインタフェース 詳細については、『SuperH RISC engine C/C++コンパイラ ユーザーズマニュアル』を参照 してください。 4.1.1 外部名の相互参照方法 (1)アセンブリ言語プログラムの外部定義名を C 言語プログラムで参照する方法 C 言語プログラムからアセンブリ言語プログラムの外部定義名を参照するには、次のように します。 • アセンブリ言語プログラムで先頭に"_"を付けたシンボル名(32 文字以内)を".EXPORT" または".GLOBAL"アセンブラ制御命令を用いて外部定義宣言します。 • C 言語プログラムでは"extern"記憶クラス指定子を用いて先頭に"_"がないシンボル名を外 部参照宣言します。 アセンブリ言語プログラム(定義する側) .EXPORT .SECTION _a : .DATA.L _b : .DATA.L .END _a , _b D, DATA, ALIGN=4 1 1 C言語プログラム(参照する側) extern int a , b; f () { a+=b; } 図 4.1 アセンブリ言語プログラムの外部定義名を C 言語プログラムから参照する例 (2)C 言語プログラムの外部定義名をアセンブリ言語プログラムで参照する方法 C 言語プログラムにとっての外部定義名とは次のものです。 • 大域変数であって、かつ static 記憶クラスでないもの • extern 記憶クラスで宣言されている変数名 • static 記憶クラスを指定されていない関数名 アセンブリ言語プログラムから C 言語プログラムの外部定義名を参照するには、次のように します。 • C 言語プログラムでシンボル名(先頭に_がない)を外部定義(グローバル変数)します。 • アセンブリ言語プログラムでは".IMPORT "または".GLOBAL "アセンブラ制御命令を用い て先頭に"_"を付加したシンボル名を外部参照宣言します。 273 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 C 言語プログラム(定義する側) int アセンブリ言語プログラム(参照する側) a; .IMPORT .SECTION MOV.L MOV.L ADD RTS MOV.L A_a: .DATA.L .END _a P,CODE, ALIGN=2 A_a, R1 @R1, R0 #1,R0 R0,@R1 _a 図 4.2 C 言語プログラムの外部定義名をアセンブリ言語プログラムから参照する例 【注】 関数名、静的データメンバから生成する外部名は、C++コンパイルのとき一定の規則で変 換を行っています。コンパイラが生成した外部名を知る必要があるときは、コンパイラオ プション code=asm または、listfile にてコンパイラが生成する外部名を参照してください。 「SuperH RISC engine C/C++コンパイラユーザーズマニュアル 付録 G エンコード規則」 もあわせて参照してください。また、C++の関数を「extern “C”」を付与して関数定義を行 えば、外部名は C の関数と同様の生成規則になります。ただし、その関数を多重定義でき なくなります。 4.1.2 関数呼び出しのインタフェース C 言語プログラムとアセンブリ言語プログラムとの間で相互に関数呼び出しを行うとき、アセン ブリ言語プログラム側で守るべき規則には、次の 4 つがあげられます。 (1)スタックポインタに関する規則 (2)スタックフレームの割り付け/解放に関する規則 (3)レジスタに関する規則 (4)引数とリターン値の設定/参照に関する規則 ここでは、(1)∼(3)までを説明します。(4)については、「4.1.3 引数とリターン値の設定/参照」 を参照してください。 (1)スタックポインタに関する規則 スタックポインタの指すアドレスよりも下位(0 番地の方向)のスタック領域に、有効なデ ータを格納しないでください。スタックポインタより下位アドレスに格納されたデータは、 割り込み処理で破壊される可能性があります。 (2)スタックフレームの割り付け/解放に関する規則 関数呼び出しが行なわれた時点(JSR または BSR 命令の実行直後)では、スタックポイン タは呼び出し関数側で使用したスタックの最下位アドレスを指しています。この領域より上 位アドレス(H'FFFFFFFF 番地の方向)のデータの割り付け/設定は呼び出し側の関数の役目 です。 関数のリターン時は、呼び出された関数で確保した領域を解放してから、通常 RTS 命令を 用いて呼び出し関数へ返ります。これより上位アドレスの領域(リターン値アドレスおよび 引数の領域)は、呼び出し側の関数で解放します。 274 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 関数呼出し直後、または呼び出された関数のリターン直後 0 下位アドレス ↑ 呼び出される側で 使用するスタック SP → リターン値アドレス 引数領域 上位アドレス ↓ 呼び出し側で 使用するスタック 図 4.3 スタックフレームの割り付け/解放 (3)レジスタに関する規則 C/C++コンパイラが関数呼び出し前後において、値を保証するレジスタと保証しないレジス タがあります。レジスタの保証規則を表 4.1 に示します。 表 4.1 C 言語プログラムでの関数呼び出し前後のレジスタ保証規則 項番 1 項目 対象レジスタ 保証しない R0∼R7 レジスタ FR0∼FR11*1 DR0∼DR10*2 アセンブリ言語プログラミングにおける注意点 関数呼び出し時に対象レジスタに有効な値があれ ば、呼び出し側で値を退避する。呼び出される側の 関数では退避せずに使用できる。 FPUL*1,*2,FPSCR*1,*2 R8∼R15 2 保証する MACH,MACL,PR レジスタ FR12∼FR15*1 DR12∼DR14*2 対象レジスタのうち関数内で使用するレジスタの値 を退避し、リターン時に回復する。ただし、"-macsave = 0"オプション指定時は MACH、MACL は保証しない レジスタ。 【注】 *1:SH-2E,SH-3E,SH-4 の単精度浮動小数点用レジスタです。 *2:SH-4 の倍精度浮動小数点用レジスタです。 C言語プログラムとアセンブリ言語プログラムの関数の接続は、次のようにしてくだい。 (a)アセンブリ言語関数を C 言語プログラムから呼び出す場合 • 対象アセンブリ言語関数が別のモジュールを呼び出しているときには、アセンブリ言語 関数の入口で PR レジスタの値のスタックへの退避、出口でスタックからの回復を行っ てください。 • アセンブリ言語関数内で R8∼R15、MACH、MACL のレジスタを使用するときには、使 用前にレジスタ値のスタックへの退避、使用後にスタックからの回復を行ってください。 • アセンブリ言語関数へどのように引数が渡されるかについては「4.1.3 引数とリターン 値の設定/参照」を参照してください。 275 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (b)C 言語関数をアセンブリ言語プログラムから呼び出す場合 • R0∼R7 レジスタに有効な値があれば、C 言語関数呼び出し前に空きレジスタまたはスタ ックへ値を退避してください。 • アセンブリ言語関数へどのようにリターン値が渡されるかについては「4.1.3 引数とリ ターン値の設定/参照」を参照してください。 C言語関数 f からアセンブリ言語関数 g を呼び出し、さらにアセンブリ言語関数 g から C 言語関 数 h を呼び出している例を図 4.4 に示します。 C言語関数f extern void g( ); f( ) { g( ); } アセンブリ言語関数 g .EXPORT .IMPORT .SECTION _g : STS.L MOV.L MOV.L : MOV.L MOV.L MOV.L JSR NOP : MOV.L MOV.L RTS LDS.L _g _h P, CODE, ALIGN=2 PR ,@-R15 R14,@-R15 R13,@-R15 関数gの外部定義宣言 関数hの外部参照宣言 R2,@R15 R1,@R15 L_h,R0 @R0 関数hでの使用レジスタの保存 @R15+,R13 @R15+,R14 関数gでの使用レジスタの回復 @R15+,PR PRレジスタ値の回復 L_h : .DATA.L .END _h PRレジスタ値の保存 関数gでの使用レジスタの保存 関数hの呼び出し C 言語関数 h h( ) { : : } 図 4.4 C 言語プログラム関数とアセンブリ言語プログラム関数の相互呼び出し例 276 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.1.3 引数とリターン値の設定/参照 C/C++コンパイラの引数とリターン値の設定/参照に関する規則は、関数宣言において個々の引 数とリターン値の型が明示的に宣言されているかどうかによって異なります。C 言語プログラムで 引数とリターン値の型を明示的に宣言するには、関数の原型宣言を用います。 以下の説明では、まず C 言語プログラムでの引数とリターン値に対する一般的な規則について述 べたあと、引数の割り付け領域と割り付け方、およびリターン値の設定場所について述べます。 (1) C 言語プログラムでの引数とリターン値に対する一般的な規則 (a)引数の渡し方 引数の値を、必ずレジスタまたはスタック上の引数の割り付け領域にコピーしたあとで 関数を呼び出します。呼び出し側の関数では、リターン後に引数の割り付け領域を参照す ることはありませんので、呼び出された側の関数で引数の値を変更しても呼び出し側の処 理は直接には影響を受けません。 (b)型変換の規則 引数を渡す場合、またはリターン値を返す場合、自動的に型変換を行うことがあります。 型変換の規則について表 4.2 に示します。 表 4.2 型変換の規則 型変換 型の宣言された引数の型変換 変換方法 原型宣言によって型が宣言されている引数は、宣言され た型に変換します。 原型宣言によって型が宣言されていない引数は、次の規 則に従って変換します。 型の宣言されていない引数の型変換 ・ char 型、unsigned char 型、short 型、unsigned short 型の引数は、int 型に変換します。 ・ float 型の引数は、double 型に変換します。 ・上記以外の型は変換しません。 リターン値の型変換 リターン値は、その関数の返す型に変換します。 277 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 例 1) 原型宣言により型が宣言されている例 long f(); long f() { float x; : : return x; } リターン値 x は、原型宣言に従って long 型に変換されます。 例 2) 原型宣言により型が宣言されていない例 1 void p(int,...); long f() { char c; : p(1.0, c); : } 第 1 引数は、対応する引数の型が int 型なので、int 型に変換されます。 第 2 引数は、対応する引数の型がないので、int 型に変換されます。 例 3) 原型宣言により型が宣言されていない例 2 原型宣言によって引数の型を宣言していない場合、正しく引数が渡されるように呼び出 される側と呼び出す側で同じ型に指定してください。型が合っていない場合は、動作が保 証されません。 void f(x) float x; { : : } void main() { float x; f(x); } この例では、 関数 f の引数の原型宣言がないため、 関数 main の側で呼び出すときに引数 x を double 型に変換します。一方、関数 f の側では引数を float 型として宣言しています。このため、正しく 引数を受け渡しすることはできません。原型宣言によって引数の型を宣言するか、関数 f の側の 引数宣言を double 型にする必要があります。 原型宣言によって正しく引数の型を宣言すると次のようになります。 void f(float x) { : : } void main() { float x; f(x); } 278 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (2) C言語プログラムでの引数の割り付け方 引数は、レジスタに割り付ける場合とレジスタに割り付けられないときスタック上の引数領域に 割り付ける場合があります。引数の割り付け領域を図 4.5 に、引数割り付け領域の一般規則を表 4.3 にそれぞれ示します。 スタック ↑下位アドレス SP→ リターン値アドレス 引数領域 ↓上位アドレス 引数格納用レジスタ R4 R5 R6 R7 引数割り付け領域 FR4(DR4) FR5 FR6(DR6) FR7 FR8(DR8) FR9 FR10(DR10) FR11 (CPUがSH-2E,SH-3E,SH-4の場合) 図 4.5 C 言語プログラムでの引数割り付け領域 279 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 表 4.3 C 言語プログラムでの引数割り付けの一般規則 割り付け規則 レジスタで渡される引数 引数格納用 対象の型 スタックで渡される引数 レジスタ R4∼R7 char, unsigned char, bool, short, unsigned short, int, unsigned int, long, unsigned long, (1)引数の型がレジスタ渡しの対象 の型以外のもの (2)プロトタイプ宣言により可変個 の引数を持つ関数として宣言して いるもの*3 float(CPU が SH-1、SH-2、SH-3 の 場合),ポインタ,データメンバへのポ (3)他の引数がすでに R4∼R7 に割 り付いている場合 インタ,リファレンス FR4∼FR11*1 SH-2E、SH-3E のとき ・引数が float 型 ・引数が double 型かつ (4)他の引数がすでに FR4(DR4) ∼FR11(DR10)に割り付いている 場合 double=float オプション指定 SH-4 のとき ・引数型が float 型かつ fpu=double オプション指定なし ・引数型が double 型かつ fpu=single オプション指定 DR4∼DR10*2 SH-4 のとき ・引数型が double 型かつ fpu=single オプション指定なし ・引数型が float 型かつ fpu=double オプション指定 【注】 *1:SH-2E,SH-3E,SH-4 の単精度浮動小数点用のレジスタです。 *2:SH-4 の倍精度浮動小数点用レジスタです。 *3:プロトタイプ宣言により可変個の引数をもつ関数として宣言している場合、宣言の中で対 応する型のない引数およびその直前の引数はスタックに割り付けます。 例) int f2(int, int, int, int,...); f2(a, b, c, x, y, z) { : } 第 4 引数までは通常、レジスタに割り付けますが、ここでは x,y,z もスタックに割り付けます。 (a)引数格納用レジスタへの割り付け 引数格納用レジスタには、ソースプログラムの宣言の順に番号の小さいレジスタから割 り付けます。引数格納用レジスタの割り付け例を例 1 に示します。 (b)スタック上の引数領域への割り付け スタック上の引数領域には、ソースプログラム上で宣言した順に下位アドレスから割り 付けます。引数格納用スタックの割り付け例を例 2∼例 8 に示します。 280 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 【構造体、共用体型引数に関する注意】 構造体、共用体型の引数を設定する場合は、その型の境界調整にかかわらず 4 バイト境界に 割り付けられ、しかもその領域として 4 の倍数バイトの領域が使用されます。これは、SuperH マイコンのスタックポインタが 4 バイト単位に変化するためです。 例 1) レジスタの対象の型である引数は、宣言順にレジスタ R4∼R7 に割り付けます。 int f(char,short,int,float); : f(1,2,3,4.0); : R4 R5 R6 R7 保証しない 保証しない 1 2 3 4.0 例 2) レジスタに割り付けることができなかった引数は、スタックに割り付けます。また、引数の 型が(unsigned )char 型、または、( unsigned )short 型でスタック上の引数領域に割り付く 場合、4 バイトに拡張して割り付きます。 1 R4 int f(int,short,long,float,char); 保証しない 2 R5 : 3 R6 f(1,2,3,4.0,5); 4.0 R7 : ↑下位アドレス 引数領域 (スタック) 保証しない 5 ↓上位アドレス 例 3) レジスタに割り付けられない型の引数は、スタックに割り付けます。 struct s{int x,y;}a; int f(int,struct s,int); : f(1,a,3); : R4 R5 1 3 ↑下位アドレス 引数領域 (スタック) a.x a.y ↓上位アドレス 281 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 例 4) プロトタイプ宣言により可変個の引数を持つ関数として宣言している場合、対応する型のな い引数およびその直前の引数は、宣言順にスタックに割り付けます。 int f(double, int, int...) : f(1.0, 2, 3, 4) : R4 2 ↑下位アドレス 引数領域 (スタック) 1.0 3 4 ↓上位アドレス 例 5) 原型宣言がない場合 → char 型は int 型に、float 型は double 型に拡張して割り付ける R4 a int f ( ) char a ; float b; f (a ,b) ↑下位アドレス 引数領域 (スタック) b ↓上位アドレス 例 6) 関数の返す型が 4 バイトを越える場合またはクラスの場合、引数領域の直前にリターン値ア ドレスを設定します。また、クラスのサイズが 4 の倍数バイトでないとき、空領域が生じま す。 struct s{char x,y,z;}a; double f(struct s); : f(a); ↑下位アドレス 引数領域 (スタック) リターン値アドレス a.x a.y a.z 空領域 ↓上位アドレス リターン値設定領域 282 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 例 7) CPU が SH-2E、SH-3E の場合、float 型の引数は FPU レジスタに割り付きます。 int f(char,float,short,float,double); : f(1,2.0,3,4.0,5.0); : R4 R5 R6 R7 保証しない 保証しない 1 3 FR4 FR5 FR6 FR7 FR8 FR9 FR10 FR11 2.0 4.0 ↑下位アドレス 引数領域 (スタック) 5.0 ↓上位アドレス 例 8) CPU が SH-4 かつ-fpu オプション指定なしの場合、float/double 型の引数は FPU レジスタに 割り付きます。 int f(char,float,double,float,short); : f(1,2.0, 4.0,5.0,3); : R4 R5 R6 R7 保証しない 保証しない 引数領域 (スタック) 1 3 FR4 (DR4) FR5 FR6 (DR6) FR7 FR8 (DR8) FR9 FR10 (DR10) FR11 2.0 5.0 4.0 ↑下位アドレス ↓上位アドレス 283 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (3)C 言語プログラムでのリターン値の設定場所 関数のリターン値の型により、リターン値をレジスタに設定する場合とスタックに設定する 場合があります。リターン値の型と設定場所の関係は表 4.4 を参照してください。 関数のリターン値をスタックに設定する場合、リターン値はリターン値アドレスの指す領域 に設定します。呼び出す側では、引数領域のほかにリターン値設定領域を確保し、そのアドレ スをリターン値アドレスに設定してから関数を呼び出します(図 4.6 参照)。関数のリターン 値が void 型の場合、リターン値を設定しません。 表 4.4 C 言語プログラムでのリターン値の型と設定場所 リターン値の型 No 1 リターン値の設定場所 (singed) char, unsigned char, R0 : 32 ビット (singed) short, unsigned short, ( signed) char,unsigned char の上位 3 バイト、(signed) short,unsigned short の上位 2 バイトの内容は保証しません。 (ただし、-rtnext オプション指定時は(signed) char,(singed) short 型は符号拡張、unsigned char,unsigned short 型はゼロ 拡張を行います。) (singed) int, unsigned int, long, unsigned long, float, ポインタ, bool リファレンス、データメンバへのポインタ FR0 : 32 ビット (1)SH-2E、SH-3E のとき ・リターン値が float 型 ・リターン値が double 型かつ double=float オプション指 定 (2)SH-4 のとき ・リターン値が float 型かつ fpu=double オプション指定な し ・リターン値が浮動小数点型かつ fpu=single オプション指 定 2 double, long double リターン値設定領域(メモリ) 構造体、共用体、クラス型、 DR0:64 ビット 関数メンバへのポインタ SH-4 のとき ・リターン値が double 型かつ fpu=single オプション指定 なし ・リターン値が浮動小数点型かつ fpu=double オプション 指定 スタック ↑下位アドレス SP→ リターン値 アドレス (呼び出し側 で確保) リターン値設定領域 引数領域 ↓上位アドレス 図 4.6 C 言語プログラムでリターン値をスタックに設定する場合のリターン値の 設定領域 284 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 リンケージエディタとの関連 4.2 4.2.1 ROM 化支援機能 ロードモジュールを ROM に書き込む際、初期化データ領域も ROM に書き込まれてしまいます。 しかし、データ操作は RAM 上で行わなければならないので、起動時に初期化データ領域の ROM から RAM への複写が必要です。リンケージエディタの ROM 化支援機能を用いることにより、こ の処理を容易に実行できます。 ROM 化支援機能を使用するには、リンク時にオプション"ROM(D,R)"(D:ROM 上の初期化 データ領域のセクション名、R:RAM 上の初期化データ領域のセクション名)を指定します。 ROM 化支援機能では、次の事項が行われます。 (1) ROM 上の初期化データ領域と同じ大きさの領域を RAM 上に確保します。図 4.7 にメ モリへの二重割り付け方を示します。 ROM (D,R) D:ROM上の初期化データ領域のセクション名 R:RAM上の初期化データ領域のセクション名 ROM領域 初期値(D) 初期化データ領域(D) 初期化データ領域(R) RAM領域 オブジェクト リンケージエディタの割り付け 図 4.7 ROM 化支援機能によるメモリ割り付け (2) 初期化データ領域に宣言したシンボルの参照が RAM 領域のアドレスを指すようにアド レス解決を自動的に行います。 ユーザはスタートアップルーチンに ROM 上のデータを RAM 上に複写する処理を組み込んで おきます。例については「1.6.4 初期化部の作成」を参照してください。 ROM 化支援機能の詳細については、 『H シリーズ リンケージエディタ ライブラリアン オ ブジェクトコンバータユーザーズマニュアル』を参照してください。 なお、本機能は H シリーズリンケージエディタ Ver.4 以降でサポートしています。 285 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.2.2 リンク時の注意事項 C/C++コンパイラが生成したリロケータブルオブジェクトファイルをリンクした際、出力される エラーメッセージへの対処方法を表 4.5 に示します。 表 4.5 リンク時のエラーメッセージへの対処方法 項番 現象 確認内容 対処方法 1 リンク時にエラー No. 314 cannot found section が出力される。 リンケージエディタの start 正しいセクション名を指定して オプションにおいて、コン ください。 パイラ出力のセクション名 を大文字で指定している か。 2 リンク時にエラー No. 105 undifined external symbol が出力される。 C/C++プログラムとアセン ブリプログラム間で変数を 相互参照している場合、ア センブリプログラム内で下 線を付加しているか。 正しい変数名で参照してくださ い。 C/C++プログラムで C ライ リンク時に入力ライブラリとし ブラリ関数を使用していな て標準ライブラリを指定してく いか。 ださい。 未定義参照シンボル名が__ で始まっていないか。 (標準ライブラリ中の実行 時ルーチンを使用していま す) C ライブラリ関数の標準入 出力ライブラリを使用して いないか。 3 低水準インタフェースルーチン を作成してリンクしてくださ い。 C/C++ソースレベルデバッグができない。 コンパイル時に debug オプ コンパイル時に debug オプシ ション、リンク時に sdebug ョン、リンク時に sdebug オプ オプションを指定したか。 ションを指定してください。 リンケージエディタの Ver.5.3 リンケージエディタの Ver.5.3 以上を使用している 以上を使用してください。 か。 4 リンク時に、エラー No. 108 relocation size GBR ベース変数の指定で、 制限を越えるデータに対し、 指定した変数のオフセット #pragma gbr_base/ gbr_base1 overflow が出力される。 は制限内におさまっている 宣言を削除してください。 か。 5 リンク時に、エラー No. 104 duplicate symbol が出力される。 同じ名称の変数または関数 を複数のファイル内で外部 定義していないか。 名前を変更するかまたは static を指定してください。 複数のファイルでインクル ードされるヘッダファイル 内で変数または関数を外部 定義していないか。 static を指定してください。 (#pragma inline/ inline_asm 指定した関数でも同様です) なお、オブジェクトファイルがデバッグ情報付きであっても、リンク時に"-sdebug"オプションを 指定しないとデバッグ情報ファイルは出力されません。このとき、シミュレータ・デバッガでのソ ースレベルデバッグは行えなくなります。 286 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.3 シミュレータ・デバッガとの関連 ロードモジュールをシミュレータ・デバッガを用いて実行した場合、"MEMORY ACCESS ERROR" を発生する可能性があります。安全のため、下記の回避方法のどちらかを適用してください。 (1) シミュレータ・デバッガ使用時も実機と同様のメモリをマッピングする(必ず 1 つのセク ションの総バイト数は 4 の倍数になる)。 (2) リンク時、P セクションを除くすべてのセクションの後に下記のアセンブリ言語プログラ ムから作成するダミーセクションをリンクする。 アセンブリ言語プログラム .SECTION DM,DUMMY,ALIGN=1 .RES.B 3 .END リンク時の結合例 • コマンドオプションの場合 -START=P,C,DM/0400,B,DM,D,DM/01000000 • サブコマンドファイルの場合 START P,C,DM(0400),B,DM,D,DM(01000000) シミュレータ・デバッガを用いてソースレベルデバッグを行う際の注意事項を以下に示します。 (1)リンケージエディタは、Ver.6.0 以上を使用してください。 (2)コンパイル時には"-debug"オプションをリンク時には"sdebug"オプションを指定してくだ さい。 (3)関数内で当該関数のローカルシンボルを参照できないことがあります。 (4)1 行のソース行に複数のステートメントを記述した場合、1 つのステートメントしか表示 できません。 (5)最適化により消失したソース行のデバッグはできません。 (6)最適化により行の入れ替え等が発生するため、プログラムの実行順序や逆アセンブル表 示がソースリストの記述順序とは異なる場合があります。 例) C 言語プログラム 12 for (i=0; i<6; i++) 13 { 14 j = i+1; 15 j++; 16 } 17 j++; シミュレータ・デバッガでの逆アセンブル表示 14 j = i+1; 12 for (i=0; i<6; i++) 17 j++; (7)for 文、while 文はループ文の入口と出口で 2 回逆アセンブル表示を行うことがあります。 287 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.4 日立統合化環境 4.4.1 日立統合化環境からのオプション指定方法 Options メニューからオプションを指定することができます。日立統合化環境からのオプション 指定方法を示します。 ■C/C++コンパイラ Options メニューから SH C/C++ Cpmpiler…を選択し、SH C/C++ Cpmpiler Options(Debug)ダイア ログボックスを開きます。 (1)[Source]タグ 表 4.6 [Source]タグの項目名とコンパイルオプションの対応表 ダイアログボックス コンパイルオプション Show entries for Include Files Directroies -include=<パス名> Preinclude Files -preinclude=<ファイル名> Defines -define=<マクロ名>=<名前> /<マクロ名>=<定数> / <マクロ名> 図 4.8 [Source]タグのダイアログボックス 288 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (2)[Object]タグ 表 4.7 [Object]タグの項目名とコンパイルオプションの対応表 ダイアログボックス コンパイルオプション Object file Type -code=machinecode/asmcode Genereate debug information -debug/-nodebug Section Program section (P) -section=program=<セクション名> Const section (C) -section=const=<セクション名> Data section (D) -section=data=<セクション名> Uninitialized data section (B) -section=bss=<セクション名> 省略時:( p=P, c=C, d=D, b=B ) Store string data in -string=const/data Use 16bit short address -abs16=run/all Output directory -objectfile=<ファイル名> 図 4.9 [Object]タグのダイアログボックス 289 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (3)[List]タグ 表 4.8 [List]タグの項目名とコンパイルオプションの対応表 ダイアログボックス コンパイルオプション Generate List File -listfile[=<ファイル名>]/nolistfile Contents -show Object list -show=object/noobject Statistics -show=statistics/nostatistics Source code list -show=source/nosource After include expansion -show=include/noinclude After macro expansion -show=expansion/noexpansion 図 4.10 [List]タグのダイアログボックス -nolist と-show オプションでは-nolist オプションが優先して評価されます。 290 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (4)[Optimize]タグ 表 4.9 [Optimize]タグの項目名とコンパイルオプションの対応表 ダイアログボックス コンパイルオプション Optimization -optimeize=0/1 Speed or size Optimize for speed -speed Optimize for size -size Optimize for both speed and size -nospeed Generate file for inter-module optimization -goptimize Inline function nesting -nestinline=<数値> Automatic inline expansion -inline/inline=<数値>/noinline Switch statement -case=ifthen/table 図 4.11 [Optimize]タグのダイアログボックス • Speed or Size は Optimize for both speed and size を選択してください。 291 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (5)[CPU]タグ 表 4.10 [CPU]タグの項目名とコンパイルオプションの対応表 ダイアログボックス コンパイルオプション CPU -cpu=sh1/sh2/sh2e/sh3/sh3e/sh4 Division -division=cpu/peripheral/nomask Endian -endian=big/little FPU -fpu=single/double Round to -round=zero/near Denormalized number allower as a result -denormalization=off/on Position Independent Code (PIC) -pic=0/1 Treat double as float -double=float 図 4.12 [CPU]タグのダイアログボックス 292 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 ■OptLinker Options メニューから SH IM OptLinker optios…を選択し、SH IM OptLinker optios(Debug)ダイア ログボックスを開きます。 (6)[Input]タグ 表 4.11 [Input]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション Input files Relocatable files and object files Input *1 Library files Library Defines Define Use entry point Entry Use external subcommand file Subcommand *1:プロジェクトに登録されているファイルについては明示的に追加する必要はなく コンパイル/アセンブルしないオブジェクト等をリンクする場合に指定する。 図 4.13 [Input]タグのダイアログボックス 293 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (7)[Output]タグ 表 4.12 [Output]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション Form of load module ELF,SYSROF,SYSROFPLUS Type of lode module Form=a/r Debug information None Nodebug In output load module Debug In separate debug file Sdebug ROM to RAM mapped sections Rom Generate map file Print Load module directory Output 図 4.14 [Output]タグのダイアログボックス 294 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (8) [Optimize]タグ 表 4.13 [Optimize]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション Optimize Optimize Unify strings Optimize の string_unify Eliminate dead code Optimize の symbol_delete Reallocate registers Optimize の register Eliminate same code Optimize の same_code Optimize branches Optimize の branch Eliminated size Samesize Output information Information Forbit item Elimination of dead code Symbol_forbid Elimination of same code Samecode_forbid 図 4.15 [Optimize]タグのダイアログボックス 295 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (9) [Section]タグ 表 4.14 [Section]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション Relocatable section start address START Genereate external symbol file FSYMBOL 図 4.16 [Section]タグのダイアログボックス [Add]ボタンでセクションの割り付けを新しく指定することができます。 [Modify]ボタンで既に指定されたセクション名、アドレスを編集することができます。 [New Overlay]ボタンで複数のセクションを同一アドレスに割り付けることができます。 [Remove]ボタンで既に指定されたセクションを削除することができます。 セクションの並び順は[UP]/[DOWN]ボタンで変更することができます。 296 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 前頁のダイアログボックスの内容をリンケージエディタのサブコマンドファイルに記述した場合。 START RSTHandler START INITHandler,VECTTBL,INITTBL,IntPRG(800) START RestPRG(1000) START P,C,D(2000) 図4.16上で START RAM_sct1:RAM_sct2(F00000) 見えている部分 START B,R(7F000000) START Stack(7FFFFBF0) RAM_sct1 と RAM_sct2 は同一セクションに割り付けられます。 【注】リンケージエディタ用サブコマンドファイルの詳しい作成方法は、「H シリーズ リンケージ エディタ、ライブラリアン、オブジェクトコンバータユーザーズマニュアル」を参照してください。 297 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (10)[Verify]タグ 表 4.15 [Verify]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション CPU information file path Cpu Stop linkage on CPU information warning Cpucheck 図 4.17 [Verify]タグのダイアログボックス 298 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 (11) [Other]タグ 表 4.16 [Other]タグの項目名と Optlinksh オプションの対応表 ダイアログボックス Optlinksh のオプション Exclude unreferenced external symbol Align section Align_section Check for undefined symbols Udfcheck Check for unlinked sections Check_section 図 4.18 [Other]タグのダイアログボックス 299 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.4.2 日立統合化環境からのコンパイラバージョンの指定 日立統合化環境でのコンパイラバージョンの指定方法について説明します。バージョンの指定は 日立統合化環境をアップグレードすることで可能になります。 旧バージョン(例 HEW1.0:SH5.1.0)で作成したワークスペースを新バージョン(例 HEW1.1:SH5.1A.0)でオープン時、図 4.20 の確認ダイアログを表示し、変更可能にします。旧バー ジョンのツールが登録されている場合は、図 4.19 のように[Tools -> Upgrade...]で同様のダイアログ ([Missing Version]が[Current Version]と表示されます。)を表示し、コンパイラバージョンを指定し てください。 図 4.19 Hitachi Enbedded Workshop 300 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 図 4.20 コンパイラバージョンの指定 301 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.5 4.5.1 モジュール間最適化ツール モジュール間最適化ツール概要 モジュール間最適化ツールは、コンパイラが出力した複数のオブジェクトプログラムを入力とし オブジェクトプログラムをまたがって最適化を実行した上で、リンケージエディタを起動し結合お よび編集するソフトウェアシステムです。従来コンパイラでは、最適化できなかった、複数オブジ ェクトの最適化を行います。 通常のリンクとモジュール間最適化を行った場合の処理の流れを図 4.21 に示します。 C/C++ソース プログラム モジュール間最適化ツール (optlnksh) C/C++コンパイラ 付加情報 ファイル オブジェクト プログラム 最適化処理 最適化済み オブジェクト プログラム リンケージエディタ (lnk) リンケージエディタ (lnk) ロード モジュール モジュール間 最適化済み ロード モジュール 図 4.21 通常のリンクとモジュール間最適化を行った場合の処理の流れ 【注】 optlnksh は、内部でリンカを起動しますが lnk ではないので optlnksh のオプションとして lnk のオプションを直接指定することはできません。lnk のオプションは必ずリンカのサブコマ ンドファイルを使用して指定してください。 302 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 また、本最適化ツールを使用することによりロードモジュールのフォーマットとして • ELF/DWARF フォーマット(オブジェクト部:ELF、デバッグ情報部:DWARF) • SYSROF フォーマット(オブジェクト部:SYSROF、デバッグ情報部:SYSROF) • SYSROF PLUS フォーマット(オブジェクト部:SYSROF、デバッグ情報部:DWARF) の 3 通りの出力が可能です。 【注】ロードモジュールを SYSROF フォーマット以外のフォーマットにするには、本ツールを起 動させなければなりません。 303 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 4.5.2 最適化ツールの起動方法 最適化ツールの起動するコマンドラインの形式は次の通りです。 optlnksh[△<オプション>...] 最適化ツールを実行するためには、関連ソフトウェアを使用して、次のファイルを作成する必要 があります。(括弧内は関連ソフトウェア名称) オブジェクトプログラム(SuperH RISC engine C/C++コンパイラ Ver.5.1) リンケージエディタ用サブコマンドファイル 以下、最適化ツールの基本的な操作方法をサンプルプログラムを用いて説明します。 test1.c C プログラム test1.sub リンケージエディタ用サブコマンドファイル (1)プログラムのコンパイル test1.c をコンパイルします。このとき必ず goptimize オプションを指定します。また、ここで debug オプションを指定することにより、ソースレベルデバッグを行うためのデバッグ情報を出力する ことができます。 shc△–goptimize△–debug△test1.c(RET) (2)デフォルトライブラリの設定 リンク時に使用する標準ライブラリをデフォルトライブラリとして設定します。デフォルトラ イブラリについての詳細は「H シリーズ リンケージエディタ、ライブラリアン、オブジェクトコン バータユーザーズマニュアル」を参照してください。 PC 版(DOS プロンプト使用時) : set△HLNK_LIBRARY1=< ライブラリパス> ¥shc.lib(RET) UNIX 版 : setenv△HLNK_LIBRARY1<ライブラリディレクトリ> /shc.lib(RET) (3)最適化ツールの実行 test1.obj の最適化を実施後、ロードモジュールを作成します。 ここでは、リンケージエディタ用サブコマンドファイルの指定は省略できません。必ず指定し てください。 例 1) オブジェクトプログラムの最適化、結合 optlnksh△–optimize△–subcommand=test1.sub(RET) 304 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 <test1.sub> align_section check_section input test1 entry _main sdebug start P,C(200),D,B(08000) exit ; ; ; ; ; 入力ファイル名を指定します。 実行開始の関数名を指定します。 デバッグ情報の出力を指定します。 各セクションの開始アドレスを指定します。 処理を終了します。 ■ 説明 : リンケージエディタ用サブコマンドファイルの作成方法は、「H シリーズ リンケージエディタ、 ライブラリアン、オブジェクトコンバータユーザーズマニュアル」を参照してください。 例 2) 最適化オプションの指定 optimize オプションのサブオプションによって、最適化の内容を指定することができます。 optlnksh△–optimize=speed△–subcommand=test1.sub(RET) 例 3) サブコマンドによる最適化オプションの指定 最適化ツールのオプションはサブコマンドとして、リンケージエディタ用サブコマンドフ ァイル内で指定することもできます。 optlnksh△–subcommand=test2.sub(RET) <test2.sub> align_section check_section optimize speed input test1 entry _main sdebug start P,C(200),D,B(08000) exit ; ; ; ; ; ; 最適化ツール用オプションを指定します。 入力ファイル名を指定します。 実行開始の関数名を指定します。 デバッグ情報の出力を指定します。 各セクションの開始アドレスを指定します。 処理を終了します。 (4)コマンドライン入力形式、オプションの表示 標準出力画面上にコマンドの入力形式、オプションの一覧を表示します。 optlnksh(RET) 【注】 モジュール間の最適化のオプション/サブコマンドの詳細については「SuperH RISC engine C/C++コンパイラユーザーズマニュアル 5.3 オプション/サブコマンド」を参照してく ださい。 305 4. [アセンブリ言語プログラムおよびクロスソフトとの関連 306