私は8086アセンブリ言語の初心者です。プログラムで使用されるロジックを理解し、小さなプログラムを自分で書くことができます。しかし、私はこれが何をするのか知りたいだけです:
.model small
.stack 300h
.model smallの説明は?
masm
を使用しています。
.model tiny
CS
、DS
、およびSS
がすべて同じ64KBのメモリを指しているプログラムを取得します。スタックは、この64KBセグメントの最も高い領域に配置されます。
.model small
CS
が独自のセグメントを指し、その後にDS
とSS
が指しているセグメントが続くプログラムを取得します。スタックは、SS
セグメントの最も高い領域に配置されます。
ディレクティブ.stack 300h
はMASMにスタックのサイズを通知するので、MASMはプログラムの残りの部分(データ、bss、ヒープ)がスタックと衝突するときに警告を発します。
これらのモデルの両方で、データ項目へのすべてのアクセスはニアポインターを使用して行われます。
8086は16ビットアーキテクチャであるため、64 KBを超えるメモリへのアクセスは困難です。
ポインタを使用する最も効率的な方法は、専用の16ビットレジスタ(bx
など)を使用することです。ただし、プログラムが64 KB以上にアクセスする場合は、セグメントレジスタ(es
など)も使用する必要があります。両方のアドレス指定を可能にするために、 メモリモデル が発明されました。
したがって、ディレクティブ.model small
は、小さなメモリモデル(1つのコードセグメント、1つのデータセグメント、および1つのスタックセグメント)を使用することをアセンブラーに通知し、セグメントレジスタの値は変更されません。
次のような効果があります。
命令retn
(near
サブルーチンからの戻り)をret
として書き込むことができます。アセンブラはすべてのコードが同じセグメントにあることを知っているため、すべてのサブルーチンはnear
(つまり、16ビットのアドレスを持つ)になり、すべてのret
命令はretn
を意味します。
ばかげて取るに足りない音?読む。
コードが複数のソースファイルに分散している場合、アセンブラーが何も知らないサブルーチンを呼び出すcall
命令があります。小さなメモリモデルを使用する場合、少なくとも各サブルーチンに16ビットのアドレスがあり、near呼び出しオペコードを使用できることがわかっています。
メモリモデルを宣言せずにコードを書くこともできますが、その場合はcall near
だけではなく、call
。
すべてのソースファイルが.model small
、リンカはすべてのコードセグメントを取得し、それらをすべて64 KBに収めようとします(データセグメントの場合も同じ)。これが大きすぎる場合、これは失敗する可能性があります。
小さなアセンブリプログラムは通常、メモリモデルを気にしません。大きな外部ライブラリを使用している場合を除き、64 KBのコードで複雑なプログラムを作成できます。このような場合には、 .model small
は、「メモリモデルのことは気にせず、デフォルトを使用する」ことを意味します。