len: equ 2
len: db 2
2
の代わりに使用できるラベルは同じですか?そうでない場合、各宣言書式の利点または欠点は何ですか?交換可能に使用できますか?NASMのequとdbの違いは何ですか?
len: equ 2
len: db 2
2
の代わりに使用できるラベルは同じですか?そうでない場合、各宣言書式の利点または欠点は何ですか?交換可能に使用できますか?NASMのequとdbの違いは何ですか?
最初はCのと同様equate
である:
#define len 2
実際に最終的なコードの任意の領域を割り当てないという点で、それは単に場合、次に2に等しくなるようにlen
シンボルを設定後でlen
をソースコードで使用します。これは、定数2
を使用している場合と同じです。
第がCの場合と同様に、define byte
ある:
int len = 2;
それはが実際に、スペースを割り当てるメモリの1バイト、そこ2
を記憶し、そのバイトのアドレスことがlen
を設定しません。ここで
は区別を示し、いくつかの擬似アセンブラコードです:
line addr code label instruction
---- ---- -------- ----- -----------
1 0000 org 1234
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行目は、単にそれが簡単に何が起こっているかを説明するために作るために、組み立てアドレスは1234
であることを設定します。
2行目でコードが生成されない場合、アセンブラはシンボルテーブルに2
の値を単にロードします。elen
コードが生成されていないので、アドレスは変更されません。
次に、4行目で使用すると、その値がレジスタにロードされます。
行3は、db
が異なることを示していますが、実際にはスペース(1バイト)を割り当ててその値をそのスペースに格納します。シンボルテーブルにdlen
をロードしますが、定数値2
ではなく、そのアドレスの値を1234
にします。
後で5行目でdlen
を使用すると、実際の値が2
になるように逆参照する必要があるアドレスが取得されます。
概要
NASM 2.10.09 ELF出力:
db
はどんな魔法の効果を持っていない:それは単に出力オブジェクトファイルに直接バイトを出力します。
これらのバイトがシンボルの前にある場合、シンボルはプログラムの開始時にその値を指します。
テキストセクションにある場合、バイトが実行されます。
天気あなたがdb
またはdw
などを使用しています。シンボルのサイズは指定されません。シンボルテーブルエントリのst_size
フィールドは影響を受けません。
equ
現在の行のシンボルのシンボルテーブルエントリには、st_shndx == SHN_ABS
というマジック値があります。
バイトを現在のオブジェクトファイルの位置に出力する代わりに、シンボルテーブルエントリのst_value
フィールドに出力します。
これ以外は以下の通りです。
実際に何を意味するのかを理解するには、まずthe basics of the ELF standardとrelocationを理解する必要があります。
SHN_ABS理論
SHN_ABS
は、リンカ伝えます:シンボルエントリのst_value
フィールドが値として使用される
これを「通常の」記号と対照すると、vシンボルの代わりにメモリアドレスが使用されているため、再配置を行う必要があります。
メモリを指していないため、シンボルをインライン展開することによってシンボルを実行可能ファイルから効果的に削除することができます。
しかし、それらはまだオブジェクトファイルの通常のシンボルです。doはメモリを占有し、グローバルの場合は複数のファイルで共有できます。
サンプル使用
section .data
x: equ 1
y: db 2
section .text
global _start
_start:
mov al, x
; al == 1
mov al, [y]
; al == 2
注シンボルx
リテラル値を含んでいるので、全く逆参照[]
はy
のためのようにそれまで行われてはならないこと。
我々はCプログラムからx
を使用したい場合は、私たちが何か必要があると思います:
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
あるので、我々はy
がない間x
がSHN_ABS
であることがわかります。
もSize
がy
ため0
であることを参照してください。決してdb
が、それは単一バイト幅だったことy
に語りました。 2つのバイトを割り当てるには、2つのdb
ディレクティブを追加するだけです。
そして:
objdump -dr equ
ができます:y
が再配置アドレス0x8049088
の値を得ながら
08048080 <_start>:
8048080: b0 01 mov $0x1,%al
8048082: a0 88 90 04 08 mov 0x8049088,%al
は、だから我々は、0x1
は命令にインライン化されたことがわかります。 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
は定数12さmsglenなるようにさmsglenを定義し、後で再定義しなくてもよいです。これはプリプロセッサの定義ではありません。msglenの値は、定義された場所で$の値を使って一度評価されます。参照の時点で$。ガスの
も参照してください
類似の質問:Difference between .equ and .word in ARM Assembly?.equiv
閉じガスと同等のようです。
equ:プリプロセッサ時間。 #defineに似ていますが、大部分のアセンブラには#undefがなく、右辺に固定数のアトム定数を持つことはできません。したがって、float、double、リストはほとんどのアセンブラのequディレクティブではサポートされていません。
db:コンパイル時。 dbに格納された値は、特定のオフセットでアセンブラによってバイナリ出力に格納されます。 equを使用すると、通常はハードコーディングする必要がある定数や、取得するためのmov演算が必要な定数を定義できます。 dbを使用すると、プログラムが開始される前でもデータをメモリに格納することができます。
; I am a 16 byte object at offset 0.
db '----------------'
; I am a 14 byte object at offset 16
; the label foo makes the assembler remember the current 'tell' of the
; binary being written.
foo:
db 'Hello, World!', 0
; I am a 2 byte filler at offset 30 to help readability in hex editor.
db ' .'
; I am a 4 byte object at offset 16 that the offset of foo, which is 16(0x10).
dd foo
EQUのみアセンブラは、いくつかの共通の制限とともに、EQUの
例をサポートしている最大の定数を定義することができます。ここでは
はデシベルを実証NASMですそれの。
; OK
ZERO equ 0
; OK(some assemblers won't recognize \r and will need to look up the ascii table to get the value of it).
CR equ 0xD
; OK(some assemblers won't recognize \n and will need to look up the ascii table to get the value of it).
LF equ 0xA
; error: bar.asm:2: warning: numeric constant 102919291299129192919293122 -
; does not fit in 64 bits
; LARGE_INTEGER equ 102919291299129192919293122
; bar.asm:5: error: expression syntax error
; assemblers often don't support float constants, despite fitting in
; reasonable number of bytes. This is one of the many things
; we take for granted in C, ability to precompile floats at compile time
; without the need to create your own assembly preprocessor/assembler.
; PI equ 3.1415926
; bar.asm:14: error: bad syntax for EQU
; assemblers often don't support list constants, this is something C
; does support using define, allowing you to define a macro that
; can be passed as a single argument to a function that takes multiple.
; eg
; #define RED 0xff, 0x00, 0x00, 0x00
; glVertex4f(RED);
; #undef RED
;RED equ 0xff, 0x00, 0x00, 0x00
equは画像を汚染しないため、結果のバイナリにはバイトがまったくありません。 equへのすべての参照は、そのequの右辺に置き換えられます。
NASM 2.10.09 ELF出力ニック:1)「データが生成されません」:リンク後の実行可能ファイルとRAMスペースについてはtrueですが、NASMが生成するオブジェクトファイルにはシンボルデータが含まれます。 2) "Cの#defineと似ています":ある意味では、 "equ"はシンボルを生成します。シンボルは、externを持つ他のオブジェクトファイルで使用でき、マクロには含まれません。詳細:http://stackoverflow.com/a/33148242/895245 –
良い点、@Ciro、私は意味が文脈から明らかだと思ったが、明確にするために、明確にするためにデータをコードに変更した。 '#define'に関して、類似性は必ずしも平等ではありませんが、私はそれを明確にするつもりです:-) – paxdiablo