日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 部 : 概念と方法
第 1 章:Macro-32コードの移植の準備
第 2 章:MACROコンパイラのプラットフォームごとの動作
第 3 章:ソースに対する推奨される変更と必要な変更
第 4 章:移植したコードの性能改善
第 5 章:MACROの64ビット・アドレッシングのサポート
第 2 部:リファレンス・セクション
付録 A :MACROコンパイラの修飾子
付録 B :専用の指示文
付録 C :MACROコンパイラ・ビルトイン
付録 D :VAXからAlphaまたはI64への移植用のマクロ
付録 E :64ビット・アドレッシング用のマクロ
索引
PDF
OpenVMS ホーム
HP OpenVMS MACRO コンパイラポーティングおよびユーザーズ・ガイド

HP OpenVMS MACRO コンパイラ
ポーティングおよびユーザーズ・ガイド


目次 索引



OpenVMS VAX システムでは,位置独立コード (PIC) をあるアドレス範囲から別のアドレス範囲にコピーすることができ,アセンブルと実行も正常に行われます。ソース・コード・ラベルを使用してコピーされるある範囲のコードが含まれているコードを, OpenVMS Alpha または OpenVMS I64 用にコンパイルすると, 2 つの理由で動作しません。まず,コンパイルされたコードは,ソース・コードと同じ順序でない可能性があるためです。 2 番目に, OpenVMS Alpha では,外部参照を行うためにはリンケージ・セクションが必要だという点です。リンケージ・セクションは別の psect にあるだけでなく,リンカやイメージ・アクティベータによって設定された絶対アドレスも含まれています。 OpenVMS I64 では,コードは,リンカおよびイメージ・アクティベータによって構築されたグローバル・リージョンの一部を必要とします。

推奨される変更

コードを複製するか,あるアドレス範囲から別のアドレス範囲へのコードのコピーを除去します。

3.5 静的なデータの上書き

VAX MACRO アセンブラでは,初期化済みの静的な記憶域を自由に上書きすることができます。それには,通常は ".=" 構文を使用して現在のロケーション・カウンタを変更します。

これに対し,MACRO コンパイラでは, .ASCII データ以外の既存のデータ項目が部分的に上書きされないように,上書きが制限されています。以下のものは上書きできません。

  • スカラ項目を同じサイズの別のスカラ項目で上書きすること。

  • 内容が設定されていないすべての領域 (.BLKx または ".=.+n" で宣言)。

  • .ASCII データの複数のセクションを,他の .ASCII 指示文や .BYTE 指示文で上書きすること。

推奨される変更

可能であれば,以下のいずれかの正しい形式にコードを変更してください。

  • いずれかのスカラ領域指示文 (.BYTE,.WORD,.LONG など) を使用して宣言されたデータを,同じ種類の指示文,または同じバイト数を占める指示文を使用して上書きするコード。項目は,同じ場所にあり同じサイズである必要があります。部分的に重なることはできません。次に例を示します。

    LAB1:   .WORD 1 
            .WORD 2 
            .=LAB1 
            .WORD 128 
    

  • .ASCII データの部分的な上書き
    以前書き込んだ .ASCII データの一部を, .ASCII または .BYTE を使用して上書きすることができます。 (.ASCIC および .ASCIZ は,.ASCII/.BYTE 指示文のペアとして実装されているため,.ASCIC および .ASCIZ でも .ASCII を上書きすることができます。)
    次に例を示します。

    DATA:  .ascii /abcdefg/ 
    .=data 
        .ascii /z/           ; change "a" to "z" 
    .=data 
        .byte   0            ; change "z" to 0 
    .=data+4 
        .ascii /xyz/         ; change "efg" to "xyz" 
    


    新しいデータは,以前の .ASCII 文字列の範囲内に完全に収まっている必要があります。次の例は無効です。

    DATA:  .ascii /abcdefg/ 
    .=data+4 
           .ascii /lmnop/       ; exceeds end of previous .ASCII 
    


    他の種類の指示文 (.LONG など) を使用した部分的な上書きはできません。



3.6 外部シンボルを使用した静的な初期化

外部シンボルを使用した静的な初期化のうち,いくつかの形式は使用できません。

推奨される変更

可能であれば,使用可能な形式のいずれかにコードを変更してください。そのためには,多くの場合, $xxxDEF マクロを使用して追加のシンボルを定義します。 OpenVMS Alpha システムと OpenVMS I64 システムでは,コンパイラは次の形式の式をサポートしています。

<symbol1 +/- offset1> OPR <symbol2 +/- offset2> 

ここで,OPR には以下のものが入ります。

+ 加算
- 減算
* 乗算
/ 除算
@ 算術シフト
& 論理積
! 論理和
\ 排他的論理和

symbol1symbol2 (どちらもオプション) は,外部の値または別の psect 内のラベルで, offset1offset2 には式を指定できますが,コンパイル時に定数になる必要があります。

OpenVMS I64 システムでは, ELF オブジェクト・ファイル形式の制限により, symbol1 または symbol2 がリンカでルーチンのアドレスに解決される際,減算しか行うことができません。

コンパイラは,次の形式の式をサポートしていません。

<symbol1> OPR <symbol2> 

静的な初期化の式をこの形式に変形できない場合は,コンパイラは不正な静的な初期化を報告します。演算子の優先順位が正しくなるように,括弧を使用してください。

3.7 転送ベクタ

VAX MACRO コード中に .TRANSFER 指示文があると, /noflag=directives を指定していないかぎり,コンパイラはエラーとして出力します。このオプションを指定するとメッセージは出力されませんが, .TRANSFER 指示文は無視されます。

OpenVMS VAX システムでは, VAX MACRO ソース・コード中で転送ベクタを明示的に定義することにより,共用可能イメージ中の再配置可能なコード用にユニバーサル・エントリ・ポイントを作成できます。 OpenVMS Alpha システムと OpenVMS I64 システムでは, リンカ・オプション・ファイル内でユニバーサル・エントリ・ポイントのシンボル値を宣言することで作成します。リンカは,共用可能イメージ内にシンボル・ベクタ・テーブルを作成します。これにより外部イメージは,再配置可能なユニバーサル・プロシージャ・エントリ・ポイントとストレージ・アドレスを見つけることができます。

推奨される変更

VAX MACRO のソースから転送ベクタを削除する必要があります。コンパイラが生成したオブジェクト・ファイルをリンクする際に, SYMBOL_VECTOR 文が記述されているリンカ・オプション・ファイルを指定する必要があります。 SYMBOL_VECTOR 文の中で,どこからでも参照可能な,再配置可能なシンボル (プロシージャ・エントリ・ポイントまたはデータアドレス) を記述し,それぞれに対して DATA と PROCEDURE のどちらかを指定します。

リンカは,リンカ・オプション・ファイルにシンボルを記述した順序でシンボル・ベクタを作成します。このシンボルの順序を,後の共用可能イメージの作成まで保持する必要があります。すなわち,シンボル・リストの最後にエントリを追加したり,エントリを削除することはできますが,現行のエントリは,リスト中で同じ順序を保つ必要があります。転送ベクタについての詳細は, OpenVMS Linker Utility Manual を参照してください。

3.8 算術例外

OpenVMS Alpha システムでは,算術例外の処理は OpenVMS VAX システムと違っており,互換性がありません。 OpenVMS VAX システム用に設計された,算術例外を処理する例外ハンドラでは,期待しているシグナル名と OpenVMS Alpha システムで実際に発生するシグナル名を対応付けることができません。

OpenVMS VAX システムでは,算術例外が同期的に報告されることがアーキテクチャによって保証されますが, OpenVMS Alpha システムでは,算術例外は非同期に報告されます。 OpenVMS VAX システムでは,VAX 算術命令で例外 (オーバフローなど) が発生するとすぐに例外ハンドラに入り,以降の命令は実行されません。例外ハンドラに対して報告されるプログラム・カウンタ (PC) は,失敗した算術命令のプログラム・カウンタとなります。これによりアプリケーション・プログラムは,メイン・シーケンスを再開して失敗した演算をエミュレートしたり,同等の演算や代わりとなる演算と置き換えるといったことが可能になります。

OpenVMS Alpha システムでは,例外の原因となった命令の先にあるいくつかの命令 (分岐やジャンプを含む) が実行される可能性があります。これらの命令は,失敗した命令が使用していた元のオペランドを上書きすることがあるため,例外の解釈や修正に不可欠な情報が失われます。例外ハンドラに報告される PC は,失敗した命令の PC ではなく,いくらか先にある命令の PC になります。アプリケーションの例外ハンドラに例外が報告されたときに,ハンドラが入力データを修正したり,命令を再実行することはできません。

算術例外の報告におけるこの基本的な違いにより, OpenVMS Alpha オペレーティング・システムでは,新たに単一の条件コード SS$_HPARITH が定義されており,すべての算術例外を示します。 SS$_HPARITH の例外シグナル配列については, Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications を参照してください。1

推奨される変更

アプリケーションの条件処理ルーチンが,発生した算術例外の数をカウントしているだけの場合や,算術例外が発生したら強制終了する場合は, Alpha で例外が非同期に報告されることによる影響はありません。これらの条件処理ルーチンに条件コード SS$_HPARITH のテストを追加するだけで済みます。 VAX の算術例外は OpenVMS Alpha では返されません (トランスレートされた VAX イメージからの例外を除く)。例外の原因となった演算を再実行しようとしている場合は,コードを書き換えるか,算術例外が正確に報告されるようにするためのコンパイラ修飾子または指示文を使用します。ただし,この機能を利用するためには,コンパイラはそれぞれの算術命令を使用した後に命令パイプラインから命令を取り除く必要があるため,性能に大きく影響します。

EVAX_TRAPB ビルトインを使用すると,それまでのすべてのトラップがシグナル通知されます。このビルトインは性能への影響があるため,分離する必要がある算術命令の後でのみ使用してください。

注意

1 このマニュアルはアーカイブ扱いになっています。このマニュアルの保守は行われておらず, OpenVMS ドキュメント・セットにも含まれていません。ただし,http://www.hp.com/go/openvms/doc からオンラインで参照することができます。



3.9 ページ・サイズ

ページ・サイズへの依存をコーディングする方法を標準化し,将来の変更を容易にするために,一連のマクロが開発されました。これらのマクロについては 付録 D で説明しています。

3.10 ワーキング・セットへのページのロック

通常,ページは次のようにロックされます。

  • イメージの初期化の際,イメージが動作する間,1 セクションのコードのロック。この方法では,システム・サービス $LKWSET を呼び出してページをメモリにロックします。多くの場合,$LKWSET の呼び出しは,ロック対象のコードとは別のモジュールにあります。

  • オンザフライでの,特定の操作の小さなコード・セクションのロックダウン。多くの場合,未熟なプログラマのロックダウン方法を使用します。この方法では,IPL を上げ,その IPL をロック対象コードの終わりのデータ位置として指定します。

OpenVMS Alpha システムでは,コードのページをメモリにロックする必要があるだけでなく,コードのリンケージ・セクションもロックする必要があります。この制約とその他の制約により, OpenVMS Alpha システムには LOCK_SYSTEM_PAGES,UNLOCK_SYSTEM_PAGES, PMLREQ,および PMLEND マクロがありません。

OpenVMS I64 システムでは, OpenVMS Alpha システムで発生した問題を避けるため,パラメータが参照しているイメージ全体をロックするように $LKWSET が変更されました。これにより正しい動作が保証されますが,性能が低下するおそれがあります。詳細は, OpenVMS V8.2 リリース・ノート[翻訳版] を参照してください。

推奨される変更

コードの変更を最低限にするため,どちらのケースもいくつかの新しいマクロで対処します。

イメージの初期化時に行われるロックダウンに対しては, 3 つのマクロが提供されています。そのうちの 2 つのマクロは「開始」マーカと「終了」マーカとして機能し,ロックするコードを区切ります。残りの初期化マクロは,記述子を作成し,$LKWSET を呼び出します。

未熟なプログラマのロックダウンやその他のオンザフライのロックダウンが行われていたコードをロックまたはアンロックするために,さらに 2 つのマクロが提供されています。この項で説明したアーキテクチャ上の理由から,これらのマクロはシステム・サービス呼び出し $LKWSET および $ULWSET も使用してページのロックとアンロックを行います。

ワーキング・セットにページをロックする必要があるユーザは,すでに特権コードを実行しているはずなので,これらのマクロは LIB.MLB にあります。

  注意
これら 2 つの方法 (イメージの初期化時に行われるロックダウンとオンザフライのロックダウン) を 1 つのイメージで組み合わせて使用することはできません。オンザフライのロックダウンで実行される $ULWSET サービスは,初期化時にロックされたセクションをアンロックすることもできます。イメージ全体に対してどちらかの方法を選択する必要があります。異なるソース言語からコンパイルされたモジュールが含まれるイメージでは,特に注意してください。

OpenVMS Alpha と OpenVMS I64 のアーキテクチャによるページのロックへの影響

OpenVMS Alpha システムと OpenVMS I64 システムでのワーキング・セットへのページのロックは, OpenVMS VAX システムよりもはるかに複雑です。これには以下の理由があります。

  • コードをメモリにロックするだけでは十分ではありません。コードはそのリンケージ・セクションを参照してさまざまな値やルーチンのアドレスを取得するため,リンケージ・セクションもロックする必要があります。なお, OpenVMS Alpha のリンケージ・セクションは, OpenVMS I64 のグローバル・データ・セグメントまたは GP 領域に相当します。 GP 領域は,プログラム全体に対するデータ領域であり, OpenVMS Alpha の場合のように 1 つのルーチン用ではありません。

  • コンパイラが実行する最適化により,ロックするコードの前後にラベルを追加するだけでは不十分です。コンパイラが,ラベル間にあるコードの一部をその範囲の外側に移動する可能性があるためです。

  • 未熟なプログラマの,IPL を上げ,ロック対象コードの最後の位置として IPL を指定する方法は,上記の理由に加え,以下の理由からもうまく機能しません。

    • このシーケンスは,複数の命令の実行が必要なため, IPL を参照して自動的に IPL を上げることはできません。

    • OpenVMS Alpha と OpenVMS I64 のコンパイラ技術では,コードとデータ (たとえば,IPL が格納されたロングワード) が,同じプログラム・セクションに存在することは禁止されています。

OpenVMS Alpha または OpenVMS I64 でページをワーキング・セットにロックする唯一の方法は,システム・サービス $LKWSET を呼び出すことです。

プログラム・セクション (psect) を使用したコードの線引き

ここで示すマクロでは, psect を使用して,ロックするコードのセクションを囲みます。マクロは 3 つの psect を作成し,順番に名前を付け,以下のように使用します。

  • コードの開始ラベルと終了ラベルを,それぞれ最初の psect と最後の psect に定義します。

  • コード自体は中間の psect に配置します。

すべての psect の属性が同じだとすると,リンカはイメージ内に順番に psect を格納します。同じことが,2 番目の $LKWSET 呼び出しを必要とするリンケージ・セクションにも行われる必要があります。

イメージ内のさまざまな場所にあるロック対象のすべてのコードは同じ psect に格納されるため,この psect を使用した方法では,いずれかの要求元がいずれかのセクションをロックすると,ロック可能なすべてのコードがロックされるという副作用があります。多くの場合,これは利点となります。 OpenVMS Alpha や OpenVMS I64 のページは 8KB 以上であるため,ほとんどの要求元はページレットまたはそれより小さな領域をロックします。そのため,ほとんどの時間,ロック対象のすべてのコードが単一のページに納まります。

  注意
IPL を,ページ・フォルトが発生しない 2 よりも上げることでコードをロックする場合は,その範囲内のコードが実行時ライブラリ・ルーチンやその他のプロシージャを呼び出さないことを確認してください。 VAX MACRO コンパイラは,特定の VAX 命令をエミュレートするためのルーチンの呼び出しを生成します。これらのマクロを使用するイメージは,これらのルーチンの参照がページング不可のエグゼクティブ・イメージ内のコードで解決されるように,システム・ベース・イメージとリンクする必要があります。

イメージの初期化時のロックダウン

イメージ初期化時のロックダウンでは,以下の 3 つのマクロを使用します。

  • $LOCKED_PAGE_START

  • $LOCKED_PAGE_END

  • $LOCK_PAGE_INIT

マクロ $LOCKED_PAGE_START と $LOCKED_PAGE_END は,ロックするコード・セグメントの先頭と終わりをマークします。これらのマクロで線引きされたコードには,ルーチン全体が含まれている必要があります。実行がいずれかのマクロを超えたり,ロックされたコードから外に分岐したり,外からロックされたコードの中に分岐することはできません。ロックされたコード・セクションの中に分岐した場合や,ロックされたコード・セクションから外に分岐しようとした場合,またはマクロを超えて実行しようとした場合は,コンパイラから次のエラー・メッセージが出力されます。

%AMAC-E-MULTLKSEC, Routines which share code must use the same linkage psect. 

$LOCKED_PAGE_END にはオプションのパラメータ LINK_SECT があります。これは,ルーチンを実行した後で戻るリンケージ psect を指定するために使用します。これは,$LOCKED_PAGE_START マクロが実行されたときの実際のリンケージ psect が,デフォルトのリンケージ psect ($LINKAGE) でなかった場合にだけ使用します。

マクロ $LOCK_PAGE_INIT は, $LOCKED_PAGE_START と $LOCKED_PAGE_END を使用してロック対象の領域を線引きしているイメージの初期化ルーチンで実行する必要があります。このマクロは必要な psect を作成し,$LKWSET を呼び出してコードとリンケージ・セクションをワーキング・セット内にロックします。 R0 と R1 の内容は,このマクロによって壊れます。

$LOCK_PAGE_INIT には,オプションのパラメータ ERROR があります。これは,いずれかの $LKWSET の呼び出しが失敗した場合に分岐するエラー・アドレスです。このアドレスに到達した場合,R0 には失敗した呼び出しの状態が設定され, R1 は,コードをロックするための呼び出しに失敗した場合は 0,その呼び出しは成功したものの,リンケージ・セクションをロックするための呼び出しが失敗した場合は 1 となります。

psect を使用してロックするコードを識別しているため, $LOCK_PAGE_INIT マクロは,$LOCKED_PAGE_START マクロおよび $LOCKED_PAGE_END マクロで線引きされたコードと同じモジュールにある必要はありません。 $LOCK_PAGE_INIT を実行すると,イメージ全体の線引きされたコードがすべてロックされます。

表 3-1 に,これらのマクロを使用するために必要なコードの変更を示します。線引きするラベルは, $LOCKED_PAGE_START マクロと $LOCKED_PAGE_END マクロに置き換えられています。記述子は削除され,初期化コード中の $LKWSET の呼び出しは $LOCK_PAGE_INIT に置き換えられています。

表 3-1 イメージ初期化時のロックダウン
コード・セクション VAX システム Alpha システム
データ宣言
LOCK_DESCRIPTOR:

.ADDRESS LOCK_START
.ADDRESS LOCK_END


なし。記述子はすべて削除します。
初期化
 $LKWSET_S LOCK_DESCRIPTOR

BLBC R0,ERROR
 $LOCK_PAGE_INIT ERROR

メイン・コード
LOCK_START:

Routine_A:
.
.
.
RSB
LOCK_END:
 $LOCKED_PAGE_START

Routine_A:
.
.
.
RSB
$LOCKED_PAGE_END


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.