36
len:  equ  2
len:  db   2

それらは同じで、代わりに使用できるラベルを作成してい2ますか? そうでない場合、各申告書の長所と短所は何ですか? それらは同じ意味で使用できますか?

4

3 に答える 3

60

1 つ目はequateで、C に似ています。

#define len 2

最終的なコードで実際にスペースを割り当てないという点で、lenシンボルを 2 に設定するだけです。その後、len後でソース コードで を使用すると、定数 を使用している場合と同じになります2

2 番目はdefine byteで、C に似ています。

int len = 2;

実際には、メモリに1バイトのスペースを割り当て、そこにaを格納し、そのバイト2アドレスlenに設定します。

違いを示す疑似アセンブラ コードを次に示します。

line   addr   code       label   instruction
----   ----   --------   -----   -----------
   1   0000                      org    1234h
   2   1234              elen    equ    2
   3   1234   02         dlen    db     2
   4   1235   44 02 00           mov    ax,     elen
   5   1238   44 34 12           mov    ax,     dlen

1 行目では、アセンブリ アドレスを に設定するだけで、1234h何が起こっているのかを簡単に説明できます。

2 行目では、コードは生成されず、アセンブラーは単純elenに値をシンボル テーブルにロードします2。コードは生成されていないため、アドレスは変更されません。

次に、4 行目で使用すると、その値がレジスタにロードされます。

行 3 は、dbこれが異なることを示しています。実際には、スペース (1 バイト) を割り当て、そのスペースに値を格納しています。その後、シンボル テーブルにロードされますが、定数値ではなく、dlenそのアドレスの値が与えられます。1234h2

後でdlen5 行目で使用すると、実際の値を取得するために逆参照する必要があるアドレスが取得されます2

于 2011-11-04T08:44:25.717 に答える
8

概要

NASM 2.10.09 ELF 出力:

  • db魔法のような効果はありません。出力オブジェクト ファイルにバイトを直接出力するだけです。

    これらのバイトがたまたまシンボルの前にある場合、シンボルはプログラムの開始時にその値を指します。

    テキストセクションにいる場合、バイトが実行されます。

    シンボルのサイズを指定しない、dbまたはなどを使用する天気:シンボル テーブル エントリのフィールドは影響を受けません。dwst_size

  • equ現在の行のシンボルのst_shndx == SHN_ABSシンボル テーブル エントリにマジック値を持たせます。

    現在のオブジェクト ファイルの場所にバイトを出力する代わりにst_value、シンボル テーブル エントリのフィールドに出力します。

他のすべてはこれから続きます。

それが実際に何を意味するのかを理解するには、まず ELF 標準relocationの基本を理解する必要があります。

SHN_ABS理論

SHN_ABSリンカーに次のように指示します。

  • このシンボルでは再配置は行われません
  • シンボルエントリのst_valueフィールドは値として直接使用されます

これを「通常の」シンボルと比較してください。この場合、シンボルの値は代わりにメモリアドレスであり、したがって再配置を行う必要があります。

メモリを指していないため、SHN_ABSシンボルをインライン化することにより、リンカーによって実行可能ファイルからシンボルを効果的に削除できます。

しかし、それらは依然としてオブジェクトファイルの通常のシンボルであり、そこでメモリを占有し、グローバルであれば複数のファイル間で共有できます.

使用例

section .data
    x: equ 1
    y: db 2
section .text
global _start
_start:
    mov al, x
    ; al == 1
    mov al, [y]
    ; al == 2

シンボルxにはリテラル値が含ま[]れているため、 for のように逆参照を行ってはならないことに注意してくださいy

xC プログラムから使用したい場合は、次のようなものが必要です。

extern char x;
printf("%d", &x);

そしてasmに設定します:

global x

生成された出力の経験的観察

前に述べたことを次のように観察できます。

nasm -felf32 -o equ.o equ.asm
ld -melf_i386 -o equ equ.o

今:

readelf -s equ.o

内容:

Num:    Value  Size Type    Bind   Vis      Ndx Name
  4: 00000001     0 NOTYPE  LOCAL  DEFAULT  ABS x
  5: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 y

Ndxはですので、 であるのにではないことがst_shndxわかります。xSHN_ABSy

も参照しSizeてください。そこに 2 バイトを割り当てる 2 つのディレクティブを追加するだけです。0ydbydb

その後:

objdump -dr equ

与えます:

08048080 <_start>:
 8048080:       b0 01                   mov    $0x1,%al
 8048082:       a0 88 90 04 08          mov    0x8049088,%al

したがって、再配置アドレスの値を取得し0x1ながら、それが命令にインライン化されていることがわかります。y0x8049088

Ubuntu 14.04 AMD64 でテスト済み。

ドキュメント

http://www.nasm.us/doc/nasmdoc3.html#section-3.2.4 :

EQU は、シンボルを特定の定数値に定義します。EQU を使用する場合、ソース行にはラベルが含まれている必要があります。EQU のアクションは、指定されたラベル名をその (唯一の) オペランドの値に定義することです。この定義は絶対的なものであり、後で変更することはできません。たとえば、

message         db      'hello, world' 
msglen          equ     $-message

msglen を定数 12 に定義します。その後、msglen を再定義することはできません。これもプリプロセッサ定義ではありません: msglen の値は、参照されるたびに評価され、 の値を使用するのではなく、定義の時点で $ の値 ($ の説明についてはセクション 3.5 を参照) を使用して一度評価されます$ 参照ポイントで。

こちらもご覧ください

GAS の類似の質問: ARM アセンブリでの .equ と .word の違いは? .equiv近いGASに相当するようです。

于 2015-10-15T12:12:26.163 に答える