「アセンブラの小部屋」
何が起こるか分からないアセンブラの小部屋です。
※動作確認は自己の責任において行ってください。
技術を理解できない方の流用はおやめください!
ホームに戻る 基礎知識に戻る
☆☆ アセンブラ講座 ☆☆
☆ 本講座は、ニモニックの説明は行なわず、即プログラムを打込んで
実行できることを目的としています。
なぜならこの方法が修得する一番の近道だからです。
☆ なぜ?アセンブラ
16ビットパーソナルコンピュータがMS−DOSとともに普及し、
現在ほとんどのアプリケーション・ソフトがC言語で記述されるようになり、
アセンブラは不用と思われがちですが、割込み処理、I/Oや
メモリコントロールなど実行速度が要求される部分はC言語だけでは
対応できず、アセンブラ言語を用いて記述しなければシステムを
構築することは不可能となっています。
・C言語でも可能だと言う方も居ると思いますが、それは既存のヘッダや
機種固有のサブルーチンがあるからで、それらはアセンブラで書かれています。
・一太郎V4では最初プリンタの印字速度が遅いとの事で、印字ルーチンを
C言語からアセンブラに記述しなおしたところ、120倍以上早くなったと言う
例もあります。
・アセンブラは、低級言語で理解しにくいと言われがちですが、実は高級言語で
理解しやすいのかも知れません。また、ハードのともなう計測器、制御機器の
ソフトは、ほとんどアセンブラで記述されています。
・以上の事から、アセンブラ言語の知識を得ることにより、より深く
マイクロコンピュータのシステムを知ることができます。
・アセンブラで簡単なプログラムは作成できるが、疑似命令の使い方が分らない為に
実行可能ファイルが作れないという方が居ると思います。
アセンブラは、簡単な英単語がわかれば理解できます。
とくに回路設計やハードの分る方ならば、より理解しやすいと思います。
あとは、ラベル、定数、変数等の疑似命令を少し理解すればよいだけで、
64Kバイト以内のプログラムであれば、8086固有のセグメントの概念も
ほとんど考える必要はありません。
TOPに戻る
『メモリモデル』
8086のメモリ空間は1Mバイトですが、一つのセグメントで扱える量は
最大64Kバイトです。すなわち初心者が安心して使えるメモリ領域は、
64Kバイト以内と思えば良いでしょう。
☆ 8086のメモリモデルには大きく分けてつぎの3種類が有ります。
(メモリモデルとは、プログラムとその扱えるメモリ量を表す形式を言う)
@小規模モデル
一番小さなモデルで、すべてのセグメントの合計が64Kバイトのモデル
*使用可能メモリのトータルは64Kバイト以内
A中規模モデル
複数セグメントが各64Kバイト利用可能なモデル
*使用可能メモリのトータルは256Kバイト以内
B大規模モデル
複数セグメントが各64Kバイト以上利用可能なモデル
*使用可能メモリのトータルはCPUの管理出来る範囲
『セグメントとは』
8086は、1Mバイトのメモリ空間を持っていますが、8086のレジスタはすべて
16ビット(0〜FFFFH)で構成されており、1Mバイトのアドレスを指定するには
20ビット(0〜FFFFFH)必要となります。
そこで、「セグメント」が登場したわけです。セグメントによるアドレス指定は、
効率も悪く使いにくい点もありますが、セグメントを変更しない限り64Kバイトに
固定され、8ビットCPUから移行されてきた方にとっては同じ感覚で使用でき、
またデータの管理は簡単になります。
この、セグメントの先頭アドレスを「セグメント・ベース」といい、20ビットの
数値ですが下位4ビットが必ず0Hですので、上位16ビットで表すことができ、
このセグメント・アドレスを表すのに使われるのが、セグメント・レジスタです。
下位のアドレスは、セグメント・ベースからの相対アドレスで「オフセット・アドレス」
と呼ばれ、セグメント・ベースの下位16ビットで表します。
物理アドレスは、以下のようにセグメント・ベースアドレスとオフセット・アドレスを
加算したアドレスとなります。
『物理アドレスの求めかた』
☆ ベースアドレスに下位4ビットをプラスし20ビットデータとし、それに求めたい
オフセットアドレスを足すと物理アドレスが算出されます。
この方法で、64Kバイトしかコントロールできないアドレスをカバーしている訳です。
例)CS:コードセグメント、PC:プログラムカウンタ
CSのデータが 0011010101110011B 3573H とすると
4ビットUP 00110101011100110000B 35730H となる
PCのデータが 0001100001011001B 1859H とすると
+ −−−−−−−−−−−−−−−−−−−−−−
物理アドレス 00110110111110001001B 36F89H となる
物理アドレスは 36F89F(H) −−−> 225161(D)番地となります。
Hはヘキサ(十六進数)Dはデシマル(十進数)Bはバイナリ(二進数)です
と言うわけで、16ビットで20ビットのアドレスを管理しているわけです。
『8086のレジスタとフラグ』
8086のCPU内部には、データの一時保存、各種演算処理、アドレス指定等を
行なうためのレジスタが用意されております。
1.汎用レジスタ
HiとLoの8ビットレジスタとしても使用できる16ビット幅のデータレジスタ
「AX、BX、CX、DX」のグループと分割利用は出来ないが、ポインタおよび
インデックス・レジスタ「SP、BP、SI、DI」の二つのグループに分けられます。
1)データ・レジスタ
@AXレジスタ
主にアキュムレータ、演算、入出力命令等に使用する。
ABXレジスタ
主に間接アドレス指定時に、アドレス・レジスタ、ベース・レジスタとして利用する。
BCXレジスタ
主にストリング命令、ループ、シフト、ローティト等の繰返し数や回数を設定できる。
CDXレジスタ
主に乗除演算の補助アキュムレータ、間接アドレスによる入出力に利用する。
2)ポインタ、インデックス・レジスタ
@スタック・ポインタ(SP)
スタックの最新データのアドレスを示す。新規にスタック・ポインタを
設定する時以外は変更しない事。
Aベース・ポインタ(BP)
スタック上のデータを用いるための間接アドレッシングに利用される。
また他の領域データの間接指定や転送等にも用いられる。
Bソース・インデックス(SI)
ストリング命令での転送元アドレスの指定に用いられる。
Cデスティネーション・インデックス(DI)
汎用レジスタと同様に、演算や間接アドレシングに利用され、ストリング命令では
転送先アドレスの指定に用いられる。
2.インストラクション・ポインタ
このレジスタは、次に実行する命令の入っているアドレスを示すもので、
8ビットCPUのプログラムカウンタ(PC)に相当する。
(ユーザーが値を操作する事は出来ない)
フラグは、16ビットのレジスタで構成されており、演算結果やシステム制御のための
情報が割当てられています。
1)スティタス・フラグ
@キャリイフラグ(CF)
演算命令実行後、桁上がり(キャリイ)桁下がり(ボロー)が生じた時にセットされ、
ローテイト、シフトのビット移動命令時にその時のビット状態でON/OFFされます。
(エラー判断等に良く使われる)
Aパリテイ・フラグ(PF)
演算の結果、"1"が立っているビットの数が偶数である時セットされ、奇数の時
リセットされます。
(通信やデータ出力時に利用される)
B補助キャリイ(AF)
演算の結果、下位4ビットにキャリやボローが生じた時にセットされます。
(10進演算の時に利用される)
Cゼロ・フラグ(ZF)
演算結果がゼロの時や、比較命令で結果がイコールの時にセットされます。
(分岐の判断等に良く使われる)
Dサイン・フラグ(SF)
演算結果、最上位ビットが”1”の時にセットされ”0”の時リセットされます。
(符号付き演算の時は負の数を表す。)
Eオーバーフロー・フラグ(OF)
符号付き演算処理の結果、オーバーフローが生じた時にセットされます。
2)コントロール・フラグ
@ディレクション・フラグ(DF)
ストリング命令の実行する方向を示し、実行前にこのフラグを”1”にすると
上位アドレスから下位アドレスに向って、フラグを”0”にすると下位から
上位アドレスに向って処理されます。
Aインターラプトイネーブル・フラグ(IF)
ハードウェア割込みの制御を行ない、フラグが”1”の時は割込みを受け付け、
”0”の時は受け付けを禁止します。
Bトラップ・フラグ(TF)
このフラグがセットされていると、ステップ割込みが発生しプログラムを一命令ずつ
実行させ、その動作を確認する事ができます。
3.セグメント・レジスタ
8086では、64Kバイト単位のセグメントに分れておりそれぞれ、
「コード、データ、スタック、エクストラ」等の役割に割当て専用の
セグメント・レジスタを使用します。
@コード・セグメント(CS)
実行すべき命令コードが格納されているセグメントの先頭を示す。
Aデータ・セグメント(DS)
プログラムで使用するデータが格納されているセグメントの先頭を示す。
Bスタック・セグメント(SS)
プログラムのスタック操作により、スタック・データが格納されているセグメントの
先頭を示す。
Cエクストラ・セグメント(ES)
補助的に使用するデータが格納されているセグメントの先頭を示す。
これらのセグメントは、お互に独立した四つのセグメントで、64K×4=256K
バイトのメモリ空間を利用する事が出来ます。
セグメントの値は、プログラム中で変更しない限り自動的に作成されますので、
あまり考えなくても良いでしょう。
TOPに戻る
『アセンブラの疑似命令について』
アセンブラにおいて疑似命令は必要なものですが、数種類の最低限必要な疑似命令さえ
理解できれば、簡単なプログラムを組むことができます。
疑似命令とは、ソースプログラムをアセンブルおよびリンクする時、プログラム構造の
定義、変数や定数の定義、ラベルや条件文等の必要な指示を与え参照されるものであって、
マシンコードに変換されないと言うことです。
プログラミングに最低必要な疑似命令を以下に示します。
「ラベル」
ラベルは、自分の居場所を表すためのもので、ジャンプ、ループ、コール命令等の
飛び先として用いられ、アセンブラ側でアドレス計算を自動的に行なうため、
プログラマーはアドレス計算を考える必要がありません。
「変数」
変数は、式の中で命令およびディレクティブに対するオペランドとして使用される
名前で、ある値の置かれているアドレスを表します。
定義ディレクティブは、DB(ディファイン・バイト)DW(ディファイン・ワード)
等が良く利用されます。
「シンボル」
シンボルはディファイン・ディレクティブ、またはコードヘの参照なしに定義される
名前で、変数と同様、命令およびディレクティブに対するオペランドとして式中で
使用されます。
良く利用されるディレクティブにEQUディレクティブがあります。
☆ マクロ・アセンブラによる疑似命令の分類
疑似命令を大きく分けると以下のように分けることが出来ます。
@プログラム構造定義
構造定義には、すべてのセグメントは、セグメントのはじめを表す"SEGMENT"と
終りを表す"ENDS"を、すべてのプロシージャは、プロシージャのはじめを表す
"PROC"と最後を表す"ENDP"、ソースファイルの最後を表す"END"などプログラムの
構造に関係する部分を定義します。
Aデータ定義
データ定義には、変数名の後に単位定義する"DB、DW、DD、DQ、DT"、定数を定義する
"EQU、="などデータに関係する部分を定義します。
B型指定
プログラムの命令上で用いるデータの型を指定する"BYTE PTR、WORD PTR"やセグメント
オーバーライドのOFFSET、SEG、SHORTなどアトリビュートに関係する部分を定義します。
Cモジュール関係定義
複数のファイルを用いる場合に、外部の変数名(データ、サブルーチン)を
"PUBLIC,EXTRN"などで参照を定義します。
Dマクロ定義
マクロ定義には、マクロのはじめを表す"MACRO"と終りを表す"ENDM"やIRP、LOCALなどの
定義があり、このマクロ命令を利用することで、高級言語風の記述が行えます。
マクロ命令ではマクロの名前と、引数をセットすると引数の値を引渡してオペランドに
引数をセットしてくれます。
(引数が複数ある場合は、カンマ(,)で区切ります)
マクロは、コーディングの繰返しを行なわなくても良い長所がありますが、
参照される度にマクロ定義内のコーディング部分がコピーされますので、
メモリーの使用量が多くなる短所があります。
※ メモリー効率を上げたい場合はサブルーチン化を行なったほうが良いでしょう。
E条件アセンブル定義
IF〜ELSE〜ENDIFなど特定の条件にしたがって、アセンブルを行いコードブロックを
作成する。
条件アセンブル疑似命令を利用してマクロ定義を行なえば、より高級言語風な使い方が
できますが、プログラムのデバックを行なう場合、理解しにくくなってきます。
Fリスティング指定定義
アセンブルでリストを作成する場合に、PAGE,TITLE,LIST,XLISTなどの条件に
したがって、フォーマット・コントロールとリスティング・コントロールを
おこないます。
※ 実際には、@ から C までを理解できれば問題はありません。
わたしは、マクロ命令はほとんど使いません。(スキでないからです)
TOPに戻る
『全体のプログラム書式』
☆ まず初めに、一番簡単なスモールモデルでシングルファイル形式における、
全体のプログラム体系の書式を「プログラム1」に示します。
この書式に、サブルーチンをどんどん追加していき、後は何を行なうのかを考えて、
メインルーチンを作成すればプログラムは問題なく動作します。
スタックエリアは、PUSH(プッシュ)、CALL(コール)、INT
(インターラプト、イント)命令を用いると1ワードから3ワード使用しますが、
50ワード分確保しておけば充分です。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
「プログラム1」
☆ スモール・モデルで単一ファイルの書式
※ プログラムの部分のみ別ファイルにすれば、そのままアセンブラにかけられます。
※ コード、データ、エキストラ、スタックの各セグメトのトータルで64Kバイト
までのプログラミング構造体系
BIGIN:、MAIN:、CLS: は行き先案内用のラベルである。こう言うふうにすると、跳び先の
アドレスを考えなくても、アセンブラが自動的にアドレス計算して設定します。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
;**********************************************
;****** プログラムのタイトルを入れておく ******
;**********************************************
;
CODE SEGMENT PUBLIC ;CODEと言うセグメントの始りの定義
;
ASSUME CS:CODE,DS:CODE ;コードセグメントとデータセグメントの
;名前はCODEであると定義している
ESC EQU 1BH ;ESCは1BHであると定義している
;
;ここからJMP MAINLPまでメインルーチンである
;メインルーチンを書いていく
;
BIGIN: MOV AX,SEG CODE ;CODEのセグメントデータを
;AXレジスタに持ってくる
MOV SS,AX ;スタックセグセメントをCODEに設定
MOV SP,SS:[OFFSET TOP] ;スタックポイントの位置をTOPと言う
;名前のOFFSETアドレスにセットする
MOV DS,AX ;データセグメントをCODEに設定
MOV ES,AX ;エキストラセグメントをCODEに設定
;
;****** 各種実行用の初期化を行なう ******
;
MAIN: CALL CLS ;サブルーチンCLSを呼んで画面をクリア
;
;****** メインループ ******
;
MAINLP: ;
;
JMP MAINLP ;必ずメインルーチンのどこかにジャンプ
;又はプログラムエンドでMS−DOSに
;戻るようにする
;
;**********************************
;****** サブルーチン エリア ******
;**********************************
;
;ここからサブルーチンエリアである
;サブルーチンを書いていく
;
;****** CLEAR CONSOLE ******
;
;テキスト画面をクリアするサンプル サブルーチン
;ESCシーケンスを利用するの項目を参照すること。
;
CLS: MOV DL,1BH ;ESCコードをセットしている
CALL CO ;ESCコードをコンソールに出力
MOV DL,"*" ;ESCシーケンスの画面クリアをセット
CALL CO ;ASCIIコードの*をコンソールに出力
RET
;
;****** スタック エリア ******
;
;PUSHやCALLを実行する場合、実行前のPCやフラグの状態を格納するところ
;
DUMMY DW 50H DUP(0) ;50ワード分のスタックエリアを確保
TOP DW 0 ;スタックポイントの先頭
;
;****** データ エリア ******
;
;メッセージデータや変数などのデータ領域を定義する
;
DCOLOR DB ESC,"[3?m$" ;ESCシーケンスの文字カラーのシーケンス
;そのつど一文字づつは、効率が悪いので
;データとして確保している
;
MSGD00 DB "Copyright (C) 1989 T.SUZUKI$"
;画面に出力するメッセージデータある
;
;
CODE ENDS ;CODEと言うセグメント名の最後
;
END ;プログラム全体の終り
TOPに戻る
『ファイル分割によるプログラムのモジュール化』
プログラムの容量が大きくなってくると、プログラミングをより効率良く行うために、
プログラムを分割して開発を行なう。
分割は、各機能別にモジュール化を行なわなければ効率良く作成出来なくなってきます。
以下に複数ファイルにおける「スモール・モデル」に、すぐ用いられる小規模モデルの
基本書式を示しておきます。
-------------------------------------------------------------------------------
「プログラム2」
「複数ファイルのスモールモデルの構造」
-------------------------------------------------------------------------------
;*************************************
;****** プログラム ノ タイトル ヲ イレテ オク ******
;*************************************
;
CODE SEGMENT PUBLIC ;CODE ト イウ セグメント ノ ハジマリ
;
ASSUME CS:CODE,DS:CODE ;CS:,DS:ハ CODE ノ テイギ
;
;********************************
;* EXTERN DATA SYMBOL *
;********************************
;
;他のファイルのデータや変数を利用するために定義している
;(他のファイルのデータや変数がパブリック(PUBLIC)で定義されていること)
;1WORD−−>2BYTEです
;
EXTRN FLG:BYTE,DBYTE:WORD,DADRS:WORD,FNAME:BYTE
;
;********************************
;* EXTERN SUBROUTINE *
;********************************
;
;他のファイルのサブルーチンを利用するために定義している
;(他のファイルのサブルーチンがパブリック(PUBLIC)で定義されていること)
;
EXTRN ENBTL:NEAR,STPKS:NEAR,OFCUR:NEAR
;
;********************************
;* PUBLIC DATA SYNBOL *
;********************************
;
;ファイル内のデータを他のファイルで利用できるようにデータ名を定義している
;
PUBLIC MSGD00,・・・・・・,・・・・・・
;
;****************************************
;* PUBLIC SUB ROUTINE SYMBOL *
;****************************************
;
;ファイル内のサブルーチンを他のファイルで利用できるように
;PUBLICでサブルーチン名を定義している
;
PUBLIC CLS,・・・・・・,・・・・・・
;
;****** EQUATE DATA AREA ******
;
ESC EQU 1BH ;ESC ハ = 1BH デ アル ト テイギ シテイル
;
;ココカラ JMP MAINLP マデ メインルーチン デ アル
;メイン ルーチン ヲ カイテ イク
;
BIGIN: MOV AX,SEG CODE ;CODE ノ セグメントデータ ヲ AXレジスタ ニ モッテクル
MOV SS,AX ;スタックセグセメント ヲ CODE ニ セッテイ
MOV SP,SS:[OFFSET TOP] ;スタックポイント ノ イチ ヲ TOP ト イウ ナマエ ノ
;OFFSET アドレス ニ セット
MOV DS,AX ;データセグメント ヲ CODE ニ セッテイ
MOV ES,AX ;エクストラセグメント ヲ CODE ニ セッテイ
MAIN: CALL ENBTL ;ファンクション Key メッセージ OFF ニ スル
CALL STPKS ;STOP KEY ノ ウケツケ コロス
CALL OFCUR ;カーソル ヒョウジ ヲ シナイ
CALL CLS ;ガメン クリア
MAINLP: ;
;
JMP MAINLP ;カナラズ メインルーチン ノ ドコカ ニ ジャンプ
;マタハ プログラム エンド デ MS-DOS ヘ
;*************************
;****** サブルーチン エリア ******
;*************************
;
;ココカラ サブルーチン エリア デ アル
;サブルーチン ヲ カイテ イク
;
;****** CLEAR CONSOLE ****** ;サンプル サブルーチン
;
CLS PROC NEAR ;サブルーチン CLS を外部のファイルで
;利用できるようにPROCで定義している
MOV DL,1BH
CALL CO
MOV DL,"*"
CALL CO
RET
CLS ENDP ;サブルーチンCLSの終了を定義している
;
;****** スタック エリア ******
;
DUMMY DW 50H DUP(0) ;50ワード ブン スタックエリア ヲ カクホ
TOP DW 0 ;スタックポインタ ノ セントウ
;
;
;****** データ エリア ******
;
;メッセージ データ ヤ ヘンスウ ナド ノ データ リョウイキ ヲ テイギ スル
;
DCOLOR DB ESC,"[3?m$"
MSGD00 DB "Copyright (C) 1989 T.SUZUKI$"
;
;
CODE ENDS ;CODE ト イウ セグメント メイ ノ サイゴ
;
END ;プログラム ノ オワリ
TOPに戻る
『ミデァムモデルによるプログラム』
プログラムの容量が大きくなってくると、各セグメントに64Kバイトを振分け
256Kバイトまでのプログラミング開発を行なう。
その再は、各機能別にモジュール化を行なって効率良く作成する。
以下に複数ファイルにおける「ミデァム・モデル」に、すぐ用いられる中規模モデルの
基本書式を示しておきます。
-------------------------------------------------------------------------------
「プログラム3」
「ミデァムモデルの構造」
;*************************************
;****** プログラム ノ タイトル ヲ イレテ オク ******
;*************************************
;
CODE SEGMENT PUBLIC ;CODE ト イウ セグメント ノ ハジマリ
;
;CS:,DS:,SS:,ES:の各セグメントを別々に定義する
;!!!!!ここが違う!!!!!
;
ASSUME CS:CODE,DS:DATA,SS:STACK
;
;********************************
;* EXTERN DATA SYNBOL *
;********************************
;
;ホカノ ファイル ノ データ ヤ ヘンスウ ヲ リヨウ スルタメ テイギ スル
;(PUBLIC デ テイギ サレテ イルコト)
;
EXTRN FLG:BYTE,DBYTE:WORD,DADRS:WORD,FNAME:BYTE
;
;********************************
;* EXTERN SUBROUTINE *
;********************************
;
;ホカノ ファイル ノ サブルーチン ヲ リヨウ スルタメ テイギ スル
;(PUBLIC デ テイギ サレテ イルコト)
;NEARのほかに!!FAR(64Kバイトを越える場合)!!がある
;
EXTRN ENBTL:NEAR,STPKS:NEAR,OFCUR:NEAR
;
;********************************
;* PUBLIC DATA SYNBOL *
;********************************
;
;ファイルナイ ノ データ ヲ ホカノ ファイル デ シヨウデキルヨウニ データ メイ ヲ テイギスル
;
PUBLIC MSGD00,・・・・・・,・・・・・・
;
;****************************************
;* PUBLIC SUB ROUTINE SYMBOL *
;****************************************
;
;ファイルナイ ノ サブルーチン ヲ ホカノ ファイル デ シヨウデキルヨウニ サブルーチン メイ ヲ テイギスル
;
PUBLIC CLS,・・・・・・,・・・・・・
;
;****** EQUATE DATA AREA ******
;
ESC EQU 1BH ;ESC ハ = 1BH デ アル ト テイギ シテイル
;
;ココカラ JMP MAINLP マデ メインルーチン デ アル
;メイン ルーチン ヲ カイテ イク
;
BIGIN: MOV AX,SEG STACK ;STACK ノ セグメントデータ ヲ AXレジスタ ニ モッテクル
MOV SS,AX ;スタックセグセメント ヲ STACK ニ セッテイ
MOV SP,SS:[OFFSET TOP] ;スタックポイント ノ イチ ヲ TOP ト イウ ナマエ ノ
;OFFSET アドレス ニ セット
MOV AX,SEG DATA ;DATAのセグメントデータを持ってくる
MOV DS,AX ;データセグメントをDATAにセット
MOV ES,AX ;エクストラセグメント ヲ DATA ニ セッテイ
MAIN: CALL ENBTL ;ファンクション Key メッセージ OFF ニ スル
CALL STPKS ;STOP KEY ノ ウケツケ コロス
CALL OFCUR ;カーソル ヒョウジ ヲ シナイ
CALL CLS ;ガメン クリア
MAINLP: ;
;
JMP MAINLP ;カナラズ メインルーチン ノ ドコカ ニ ジャンプ
;マタハ プログラム エンド デ MS-DOS ヘ
;*************************
;****** サブルーチン エリア ******
;*************************
;
;ココカラ サブルーチン エリア デ アル
;サブルーチン ヲ カイテ イク
;
;****** CLEAR CONSOLE ****** ;サンプル サブルーチン
;
CLS PROC NEAR ;サブルーチン CLS ヲ ガイブノ ファイル デ
;シヨウデキル ヨウニ PROC デ テイギ スル
MOV DL,1BH
CALL CO
MOV DL,"*"
CALL CO
RET
CLS ENDP ;サブルーチン CLS ノ オワリ ヲ テイギ
;
CODE ENDS ;CODEセグメントの終了
;
STACK SEGMENT STACK ;STACKセグメントの初めを定義
;
;****** スタック エリア ******
;
DUMMY DW 50H DUP(0) ;50ワード ブン スタックエリア ヲ カクホ
TOP DW 0 ;スタックポインタ ノ セントウ
;
STACK ENDS ;STACKセグメントの終了を定義
;
DATA SEGMENT PUBLIC ;DATAセグメントの初めを定義
;
;****** データ エリア ******
;
;メッセージ データ ヤ ヘンスウ ナド ノ データ リョウイキ ヲ テイギ スル
;
DCOLOR DB ESC,"[3?m$"
MSGD00 DB "Copyright (C) 1989 T.SUZUKI$"
;
DATA ENDS ;DATAセグメントの終了を定義
;
;
END ;プログラムの終了
;
------------------------------------------------------------------------------
以上がアセンブラのプログラミングを行なうための基本的な書式です。
詳しい内容については、各種マニュアルや市販の書籍をごらんください。
※簡単に述べると、スモール・モデルと、ミデァム・モデルのモジュールは、
セグメントの定義が以下のように違うだけです。
TOPに戻る
○ スモール・モデル
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODEと、すべて同じセグメント名を指定します。
(DS:CODE,ES:CODE,SS:CODEは指定しなくても良い)
=======================================
○ ミデァム・モデル
ASSUME CS:CODE,DS:DATA,ES:EXTR,SS:STACKと、作成するプログラムにより、
セグメント名を別々に指定します。
以上のように、小規模モデルと中規模モデルのセグメントを定義して、データの
処理命令時にMOV DS:・・・等とセグメント指定を、行なえば良いことがわかります。
=======================================
○ 別モジュールのデータを利用する
別モジュールのデータを用いる場合は、EXTRNで利用するデータ名とデータ形式
(バイト、ワード)を指定しなければなりません。
(利用する外部データが、別モジュールで、PUBLIC定義されていなければならない)
また指定したデータを利用する場合は、以下のように指定したデータ形式を
指示しなければエラーとなります。
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
別モジュール側で
「PUBLIC DADRS」と定義
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
利用する側で
「EXTRN DADRS:WORD」と定義
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
「MOV BX,DS:WORD PTR DADRS」この場合、データ・セグメント
内のDADRSという名前のワード・データをBXレジスタに持ってきなさいと言う
内容になります。
*詳しくは、「スモール・モデル」「ミディアム・モデル」の構造をごらん下さい。
=======================================
○ 別モジュールのサブルーチンを利用する
別モジュールのサブルーチンを用いる場合は、EXTRNで利用するサブルーチン名と
形式(NEAR(同一セグメント)、FAR(別セグメント))を指定していること。
(利用する外部サブルーチンが、別モジュールでPUBLIC定義されていること)
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
「別モジュール」で
「PUBLIC CLS」と定義
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
「利用する側」で
「EXTRN CLS:NEAR」と定義
CALL CLS
この場合、外部サブルーチンCLSを実行していますが、使用方法はモジュール内
サブルーチンと同じでPUBLICとEXTRNの定義のみが違ってきます。
TOPに戻る
-------------------------------------------------------------------------------
; 「ミデァムモデルのマルチファイル例」
;------------------------------------------------------------------------------
;ファイル名は、MAIN.ASMとする
;
CODE SEGMENT PUBLIC ;CODE ト イウ セグメント ノ ハジマリ
;
ASSUME CS:CODE,DS:DATA,SS:STACK
;
;********************************
;* EXTERN DATA SYNBOL *
;********************************
;
EXTRN FLG:BYTE,DBYTE:WORD,DADRS:WORD,FNAME:BYTE
;
;********************************
;* EXTERN SUBROUTINE *
;********************************
;
EXTRN ENBTL:NEAR,STPKS:NEAR,OFCUR:NEAR
;
;********************************
;* PUBLIC DATA SYNBOL *
;********************************
;
PUBLIC MSGD00,・・・・・・,・・・・・・
;
;****************************************
;* PUBLIC SUB ROUTINE SYMBOL *
;****************************************
;
PUBLIC CLS,・・・・・・,・・・・・・
;
;****** EQUATE DATA AREA ******
;
ESC EQU 1BH ;ESC ハ = 1BH デ アル ト テイギ シテイル
;
BIGIN: MOV AX,SEG STACK ;STACK ノ セグメントデータ ヲ AXレジスタ ニ モッテクル
MOV SS,AX ;スタックセグセメント ヲ STACK ニ セッテイ
MOV SP,SS:[OFFSET TOP] ;スタックポイント ノ イチ ヲ TOP ト イウ ナマエ ノ
;OFFSET アドレス ニ セット
MOV AX,SEG DATA ;DATAのセグメントデータを持ってくる
MOV DS,AX ;データセグメントをDATAにセット
MOV ES,AX ;エクストラセグメント ヲ DATA ニ セッテイ
MAIN: CALL ENBTL ;ファンクション Key メッセージ OFF ニ スル
CALL STPKS ;STOP KEY ノ ウケツケ コロス
CALL OFCUR ;カーソル ヒョウジ ヲ シナイ
CALL CLS ;ガメン クリア
MAINLP: ;
;
JMP MAINLP ;カナラズ メインルーチン ノ ドコカ ニ ジャンプ
;マタハ プログラム エンド デ MS-DOS ヘ
;*************************
;****** サブルーチン エリア ******
;*************************
;
;****** CLEAR CONSOLE ******
;
CLS PROC NEAR ;サブルーチン CLS ヲ ガイブノ ファイル デ
;シヨウデキル ヨウニ PROC デ テイギ スル
MOV DL,1BH
CALL CO
MOV DL,"*"
CALL CO
RET
CLS ENDP ;サブルーチン CLS ノ オワリ ヲ テイギ
;
CODE ENDS ;CODEセグメントの終了
;
STACK SEGMENT STACK ;STACKセグメントの初めを定義
;
;****** スタック エリア ******
;
DUMMY DW 50H DUP(0) ;50ワード ブン スタックエリア ヲ カクホ
TOP DW 0 ;スタックポインタ ノ セントウ
;
STACK ENDS ;STACKセグメントの終了を定義
;
DATA SEGMENT PUBLIC ;DATAセグメントの初めを定義
;
DATA END
;
END BIGIN ;プログラムの終了,スタートはBIGIN
TOPに戻る
;☆ 別ファイルのサブルーチン・プログラムリスト例(LIB.ASM)
TITLE PROGRAM LIBRARY
;
;**********************************
;* PROGRAM LIBRARY *
;**********************************
;
CODE SEGMENT PUBLIC
;
ASSUME CS:CODE,DS:DATA
;
;********************************
;* EXTERN DATA SYNBOL *
;********************************
;
EXTRN FLG:BYTE,DBYTE:WORD,DADRS:WORD,FNAME:BYTE,PBUF:BYTE,GPSETD:WORD
;
;********************************
;* PUBLIC DATA SYMBOL *
;********************************
;
PUBLIC CLS,TODOS,OFCUR,STOPKS
;
CR EQU 0DH ;CR
LF EQU 0AH ;LF
;
;********************************
;* SUB ROUTINE *
;********************************
;
;****** RETURN TO MSDOS ******
;
TODOS PROC NEAR
MOV AX,4C00H
INT 21H
RET
TODOS ENDP
;
;****** CURSOR OFF ******
;
OFCUR PROC NEAR
PUSH AX
MOV AH,12H
INT 18H
POP AX
RET
OFCUR ENDP
;
;****** INT 6H STOP KEY ******
;
STPKS PROC NEAR
PUSH DS
PUSH AX
PUSH DX
MOV AX,SEG STPKR
MOV DS,AX
MOV DX,CS:[OFFSET STPKR]
MOV AX,2506H
INT 21H
POP DX
POP AX
POP DS
RET
STPKS ENDP
;
STPKR PROC FAR
IRET
STPKR ENDP
;
CODE ENDS
;
DATA SEGMENT PUBLIC
;
DATA ENDS
;
END
TOPに戻る
☆ 別ファイルのデータ用・プログラムリスト例(DAT.ASM)
TITLE WORK DATA FILE
;
;*************************
;* WORK DATA FILE *
;*************************
;
DATA SEGMENT PUBLIC
;
ASSUME DS:DATA,ES:DATA
;
;**********************************
;**** PUBLIC DATA SYMBOL ******
;**********************************
;
PUBLIC MSGD00,MSGD01
;
CR EQU 0DH
LF EQU 0AH
;
;***************************************
;********* DATA SEGMENT ****************
;***************************************
;
;****** DISPLAY MESSAGE AREA ******
;
MSGD00 DB "PROGRAMED BY T.SUZUKI"
MSGD01 DB "????????"
;
DATA ENDS
;
END
TOPに戻る
「コンパイラの方法」
------------------------------------------------------------------------------
☆ マクロアセンブラによる開発
マクロアセンブラとは、アセンブラを高級言語風に記述できるように、疑似命令を
多くしたものと思えば良いでしょう。
以下にソース・プログラムの作成から実行可能ファイル(EXE)に変換する手順を示します。
@ ソース・プログラムを作成
ソース・プログラムの作成は、通常エディタを用いて作成しますが
(RED++,FINAL,MIFES,VZ等)、ワープロ(半角文字で)を利用してもかまいませんが
「拡張子はASM」でなければなりません。ここで打込みミスのないように考えた
プログラムを打込みます。
(8ビットでは拡張子がASM,MAC,SRC等あります)
A アセンブラ・ソフト(MASM)を起動
ソース・プログラムの打込みが終わりましたら、以下のように入力します。
・MASM ファイル名 リターンKey
拡張子がASMのファイル(この時拡張子は入力しない)
・Object filename [FILENAME.OBJ]:リターンKey
・Source listing [NUL.LST]:リターンKey
リストファイルを作成したい場合は、ファイル名を入力する。(拡張子はLST)
・Cross reference [NUL.CRF]:リターンKey
以上でアセンブルがスタートし、しばらくすると終了します。エラーがなければLINK
可能なオブジェクト・ファイル(拡張子がOBJ)が作成されます。
もしエラーが発生した場合は、もう一度ソース・プログラムをチェックしてエラー箇所を
修正してから再度アセンブルしてください。
*上記ファイルの場合
MASMとLIB98とDATA98の3種類のファイルをアセンブルしてOBJファイルを作成します。
B リンカー(LINK)を起動する
リンクとは、モジュール化されたファイルを結合して一つの実行可能なファイル(EXE)に
まとめます。
・LINK ファイル名 リターンKey
拡張子がOBJのファイル(この時拡張子は入力しない)
・Run File [FILENAME.EXE]:リターンKey
・List File [NUL.MAP]:リターンKey
・Libraries [.LIB]:リターンKey
以上でエラーがなければ実行可能な(拡張子がEXE)ファイルが作成されます。
この時スタック・エラーメッセージ(スタックを使用していない場合でも)がでる場合が
あるが、動作には問題ありません。
*上記ファイルの場合
MASMとLIBとDATAの3種類のファイルをリンクしてして実行可能なファイルを作成し、
LINK MAIN+LIB+DATA,TEST リターンで、実行可能なTEST.EXEファイルが
作成されます。
C デバック(SYMDEB)を行なう
アセンブラのソース・プログラムから実行可能なEXEファイルができましたが、
考えた目的どおりに動作するとは限りませんので、MS−DOS付属のデバッカを
用いてプログラムの動作チェックを行ないます。
動作確認してバグが発見された場合は、デバッカでプログラムを修正確認し動作が
OKならソース・プログラムを@の手順で修正してABCと繰返してバグのない完全な
プログラムに仕上げます。
TOPに戻る
☆ SYMDEBによるデ・バッグ
SYMDEBは、実行可能なEXE、COMファイルをロードして、プログラムを実行しながら
動作チェックや修正を行ないます。
SYMDEBは、プログラムコードの表示、レジスタのチェック、ブレークポイントの
設定やプログラム実行のトレースが可能であり、これらの機能を用いてプログラムを
チェックし、不良箇所が有ればその場でレジスタの値、プログラム、データ等を変更し
正常動作するようにチェック修正して行きます。
・シンボリックファイルのない場合の起動は
SYMDEB ファイル名.EXE(COM)リターンキーで、
ファイルを呼込みデ・バッグモードに入ります。
以下に、良く利用するコマンドと内容を示しておきます。
・?:ヘルプコマンドで、SYMDEBコマンドの一覧表示です。
・A:アセンブルコマンドで、指定したアドレスに、ニモニックをアセンブルして、
命令コードを入れます。
・D:ダンプコマンドで、指定したメモリの内容を、16進数とASCIIコードで
表示します。
・E:エンターコマンドで、指定したアドレスに1個または複数のバイト値を入れます。
・G:ゴーコマンドで、指定したアドレスからデ・バック中のプログラムの実行を行ない
ます。この時ブレイクポイントのアドレスも同時に設定できます。
・R:レジスタコマンドで、指定したレジスタの内容を表示し、レジスタの値を変更する
事ができます。この時ただ単にRコマンドのみですと、すべてのレジスタの内容表
示を行ないます。
・T:トレースコマンドで、指定したアドレスから指定した回数ぶん、プログラムの
実行とトレースを行ないます。
・U:逆アセンブルコマンドで、指定したアドレスからアドレスまで、逆アセンブルを
行ないます。アドレス指定を行なわないときは、現在のアドレスから8行分
逆アセンブルを行ない表示します。
TOPに戻る
☆ EXEファイルからCOMファイルへ変換
拡張子がEXEのファイルを拡張子COMのファイルに変換するには、MS−DOS付属の
ユーティリティEXE2BINを使用して変換します。
COMファイルは、EXEファイルよりファイルサイズが小さくできるメリットが
ありますが、変換できるEXEファイルは64Kバイト以内で、コードセグメントの
インストラクション・ポインタがORG 100Hで指定したものでなければなりません。
変換は
EXE2BIN ファイル名(EXE) A:ファイル名.COM
のように行ないEXEファイルの拡張子は不要で、COMファイルの拡張子は付けます。
TOPに戻る
☆ シングルファイルのプログラミングには気を付けよう
アセンブラ・プログラムを作成して、マクロアセンブラにかけると「Out of Memory」の
エラーメッセージが現れオブジェクトファイルができません。昨日までは問題なく動作
していたのにと思い、いろいろ調べていくうちに以下の事が分かりました。
@プログラムのソースファイルが大きすぎる
Aソースファイルのシンボルテーブル内のラベルが多すぎる。
※MS−DOSマニュアルには、ソースファイルの容量やラベル数等、具体的な数値は
書かれておりません。
「Out of Memory」したソースファイルの容量を見てみますと、78kバイトと120Kバイトで
した、これはラベルの数による違いですので、ソースファイルが64Kバイトを超え始めら、
マルチファイル用に疑似命令(EXTRN,PROC,PUBLIC等)を追加して、別のファイルを
作成した方がよいでしょう
TOPに戻る
|