NASMソースのデータ構造
5008 ワード
概要
NASMはモジュール化されています.再利用可能なアセンブラです.データ構造に関しては、配列、チェーン、HASHなどがあります.
詳しく説明するは、式求値プログラムで計算された値を配列記憶する. これらの生成された値はクエリーにのみ使用され、変更されないので、配列で表現するのに適しています.
このようにHASH配列の各項目はチェーンを指しています.チェーンテーブルの各結点にはマクロに関する情報が格納されています.また、各結点マクロの名前は同じHASH値を持っています.この配列とチェーンはHASHアルゴリズムで結合された構造で、指定された名前のマクロをより迅速に見つけることができます.
3.NASMは動作時に二つのメモリを動的に割り当てます.
一つのブロックはランダムメモリアクセスを行い、ツリー構造で表し、それぞれのリーフノードに実際のデータを記憶する.
もう一つのブロックは順序メモリアクセスを行い、チェーン構造で表します.
このようにプログラムは多くの小さいメモリブロックが必要な時に毎回割り当てなくてもいいです.割り当てられたメモリブロックが使い切られた時だけ割り当てます.効率を上げるだけでなく、管理も容易です.
SAA:dynamic sequential-access array.
RAA:dynamic radom access array.
各合法的な命令のテンプレートは以下の通りです.
NASMはモジュール化されています.再利用可能なアセンブラです.データ構造に関しては、配列、チェーン、HASHなどがあります.
詳しく説明する
/*
* Expression-evaluator datatype. Expressions, within the
* evaluator, are stored as an array of these beasts, terminated by
* a record with type==0. Mostly, it's a vector type: each type
* denotes some kind of a component, and the value denotes the
* multiple of that component present in the expression. The
* exception is the WRT type, whose `value' field denotes the
* segment to which the expression is relative. These segments will
* be segment-base types, i.e. either odd segment values or SEG_ABS
* types. So it is still valid to assume that anything with a
* `value' field of zero is insignificant.
*/
typedef struct {
long type; /* a register, or EXPR_xxx */
long value; /* must be >= 32 bits */
} expr;
2.HASH値で配列とチェーンを組み合わせて前処理で出会ったマクロを保存します.このようにHASH配列の各項目はチェーンを指しています.チェーンテーブルの各結点にはマクロに関する情報が格納されています.また、各結点マクロの名前は同じHASH値を持っています.この配列とチェーンはHASHアルゴリズムで結合された構造で、指定された名前のマクロをより迅速に見つけることができます.
3.NASMは動作時に二つのメモリを動的に割り当てます.
一つのブロックはランダムメモリアクセスを行い、ツリー構造で表し、それぞれのリーフノードに実際のデータを記憶する.
もう一つのブロックは順序メモリアクセスを行い、チェーン構造で表します.
このようにプログラムは多くの小さいメモリブロックが必要な時に毎回割り当てなくてもいいです.割り当てられたメモリブロックが使い切られた時だけ割り当てます.効率を上げるだけでなく、管理も容易です.
SAA:dynamic sequential-access array.
RAA:dynamic radom access array.
struct SAA {
/*
* members `end' and `elem_len' are only valid in first link in
* list; `rptr' and `rpos' are used for reading
*/
struct SAA *next, *end, *rptr;
long elem_len, length, posn, start, rpos;
char *data;
};
struct RAA {
/*
* Number of layers below this one to get to the real data. 0
* means this structure is a leaf, holding RAA_BLKSIZE real
* data items; 1 and above mean it's a branch, holding
* RAA_LAYERSIZE pointers to the next level branch or leaf
* structures.
*/
int layers;
/*
* Number of real data items spanned by one position in the
* `data' array at this level. This number is 1, trivially, for
* a leaf (level 0): for a level 1 branch it should be
* RAA_BLKSIZE, and for a level 2 branch it's
* RAA_LAYERSIZE*RAA_BLKSIZE.
*/
long stepsize;
union RAA_UNION {
struct RAA_LEAF {
long data[RAA_BLKSIZE];
} l;
struct RAA_BRANCH {
struct RAA *data[RAA_LAYERSIZE];
} b;
} u;
};
4.その他各合法的な命令のテンプレートは以下の通りです.
struct itemplate {
int opcode; /* the token, passed from "parser.c" */
int operands; /* number of operands */
long opd[3]; /* bit flags for operand types */
const char *code; /* the code it assembles to */
unsigned long flags; /* some flags */
};
ここで、第4項のコードにおいて、生成されたマシンコードに発生する可能性がある場合を特定の値で表し、例えばコマンドテンプレートに「320」が存在すると、そのコマンドには16ビットの固定サイズの操作数が必要であることを示している.このように、ターゲットコードが32ビットの場合、マシンコードは1つのオペランドプレフィックスを必要とする.