Microsoft Macro Assembler(以降、MASMと略)Version 6以降でアプリケーションを開発する際のメモ書きです。
この記事では、セグメントの指定方法について記します。
セグメント定義(MASM Version 5までの方法)
SEGMENT
~ ENDS
書式
name SEGMENT (align) (READONLY) (combine) (use) ('class')
(statements)
name ENDS
説明
セグメントの名前、区間、属性等を設定する。
パラメータ
name
セグメントの名前
align
このセグメントのアライメントを指定する。
align | 開始アドレス |
---|---|
BYTE | 1 Byte単位で配置する。 |
WORD | 2 Byte単位で配置する(偶数アドレスに配置)。 |
DWORD | 4 Byte単位で配置する。 |
PARA | 16 Byte単位で配置する(16進数で末尾1桁が0のアドレスに配置)。省略時のデフォルト |
PAGE | 256 Byte単位で配置する(16進数で末尾2桁が00のアドレスに配置)。 |
ALIGN(n) | (n) Byte単位で配置する(nは1~8192の範囲の2のべき乗を指定する)。 |
READONLY
これを指定した場合、当該セグメントは読み込み専用とする。
当該セグメントに書き込みを行う命令を記述した場合は、アセンブラーはエラーを出力する。
combine
*.obj
ファイルのリンク時の動作を指定する。
※16bit, 32bitのみ(64bit版MASMでは非対応)
combine | リンカーの動作 |
---|---|
PRIVATE | 他の *.obj ファイルから、このセグメントのアクセスを許可しない。 |
PUBLIC | 他の *.obj ファイルから、このセグメントのアクセスを許可する。 |
STACK | スタック用のセグメント。この属性のセグメントは全て連結し、OSはSS:0000 を下位アドレスに、SS:SP を上位アドレスに設定する。初期化済データの配置は不可。 |
COMMON | この属性のセグメントは結合する。初期化済データの配置は不可。 |
MEMORY | PUBLICと同義 |
AT (address) | セグメントアドレスを直接指定する。このセグメントには、コード及び、初期化済データを配置できない。当該セグメントにVRAM等の構造体を定義する事で、直接アクセスするコードを書くことが出来る。(16bitコード) |
use
オフセットアドレスの扱い
※32bitのみ(16bit、及び64bitでは非対応)
use | オフセットアドレスの扱い |
---|---|
USE16 | オフセットアドレスを16bitとして扱う。 |
USE32 | オフセットアドレスを32bitとして扱う。Visual C++で書かれた32bitコードとリンクする場合、だいたいこれを指定する。 |
FLAT |
'class'
クラス名を指定する。
リンカはメモリ内で自動的に同じクラスの区分を分類する。
class | |
---|---|
'CODE' | コード領域である事を示す。 |
'FAR_DATA' | 初期化データ領域である事を示す。 |
'FAR_BSS' | 未初期化データ領域である事を示す。 |
'DATA' | 初期化データ領域である事を示す。 |
'CONST' | 初期化データ領域である事を示す(書込み禁止)。 |
'BSS' | 未初期化データ領域である事を示す。 |
'STACK' | スタック領域領域である事を示す。 |
GROUP
書式
group_name GROUP [name]...
説明
指定したセグメントを、同一のセグメントにまとめる。
パラメータ
group_name
セグメントグループの名前。
name
セグメント名。
ASSUME
書式
ASSUME [segregister:name]...
ASSUME [dataregister:type]...
ASSUME [register:ERROR]...
説明
セグメントレジスタの値、レジスタの型を仮定する。
パラメータ
segregister
セグメントレジスタ(CS
, DS
, ES
, SS
)。
name
セグメント名、若しくは、セグメントグループ名。
dataregister
レジスタ
type
BYTE
, WORD
, DWORD
, PTR
, 等の他、PTR STRUC
といった構造体のポインタも仮定可能
例
ASSUME
ディレクティブにてDS
レジスタをname
に仮定する事で省略することができる。
ASSUME DS:DGROUP ;DSレジスタには DGROUP が設定されているものと仮定する。
MOV EAX, label ;上記仮定の元、アセンブルする(labelの実体はセグメントDGROUPに存在する)。
ASSUME
ディレクティブにて、レジスタの型を構造体に仮定する事で、構造体名を省略することができる。
ASSUME EDI:PTR STRUCT ;EDIレジスタは、構造体STRUCTのポインタが設定されているものと仮定する。
MOV EAX, [EDI].member ;上記仮定の元、アセンブルする。
簡略化セグメント(MASM Version 6以降の方法)
MASM Version 6から導入された簡易的なセグメントの指定方法。
上記のディレクティブを用いずに、セグメントの指定が行える(ASSUME DS:DGROUP
も必要ない)。
Visual C++で書かれたコードとリンクする場合、これらのディレクティブを用いてコードを記述すれば、開発しやすい。
.dosseg
書式
.dosseg
説明
セグメントの並び方を、MS-DOSの仕様にする。
MS-DOS仕様のC言語等でコンパイルした*.objファイルとリンクする場合等に記述する。
(32bit、64bitのコードでは、不要)
Segment | 配置順番 |
---|---|
heap | ヒープ領域(残りメモリ) |
STACK | スタックエリア |
BSS | 未初期化データ |
CONST | 初期化済みデータ(書き換え禁止) |
DATA | 初期化済みデータ |
FAR_BSS | far 領域の未初期化データ |
FAR_DATA | far 領域の初期化済みデータ |
_TEXT | コード領域 |
.code
書式
.code (name)
説明
次の行以降を、コード用のセグメントに設定する。
パラメータ
name
セグメントの名前を指定する。
省略した場合、メモリモデルがTINY
, SMALL
, COMPACT
, FLAT
の時は_TEXT
、
メモリモデルがMEDIUM
, LARGE
, HUGE
の時は、module_TEXT
と設定される。
.const
書式
.const
説明
セグメント名は、CONST
が設定され、
次の行以降を、書き換え不可のデータ用のセグメントに設定する。
多くのC言語における、nearがつく変数領域と同一のセグメント。
.data
書式
.data
説明
セグメント名は、DATA
が設定され、
次の行以降を、書き換え可の、初期化済みデータセグメントに設定する。
多くのC言語における、nearがつく変数領域と同一のセグメント。
.data?
書式
.data?
説明
セグメント名は、BSS
が設定され、
次の行以降を、書き換え可の、未初期化データセグメントに設定する。
多くのC言語における、nearがつく変数領域と同一のセグメント。
.fardata
書式
.fardata (name)
説明
次の行以降を、書き換え可の、初期化済みデータセグメントに設定する。
パラメータ
name
セグメントの名前を指定する。
省略した場合、セグメント名はFAR_DATA
と設定される。
.fardata?
書式
.fardata? (name)
説明
次の行以降を、書き換え可の、未初期化データセグメントに設定する。
パラメータ
name
セグメントの名前を指定する。
省略した場合、セグメント名はFAR_BSS
と設定される。
.stack
書式
.stack (size)
説明
セグメント名をSTACK
で、スタック領域を確保する。
メモリモデルがTINY
の場合は、確保されないので注意。
Visual C++で書かれたコードとリンクする時は、指定の必要はない。
(おそらく、ランタイムの方で確保されている。)
パラメータ
size
スタック領域のサイズ[byte]を設定する。
省略した場合は、1024[byte]となる。