2011-11-04 11 views

答えて

26

最初は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になるように逆参照する必要があるアドレスが取得されます。

+2

NASM 2.10.09 ELF出力ニック:1)「データが生成されません」:リンク後の実行可能ファイルとRAMスペースについてはtrueですが、NASMが生成するオブジェクトファイルにはシンボルデータが含まれます。 2) "Cの#defineと似ています":ある意味では、 "equ"はシンボルを生成します。シンボルは、externを持つ他のオブジェクトファイルで使用でき、マクロには含まれません。詳細:http://stackoverflow.com/a/33148242/895245 –

+0

良い点、@Ciro、私は意味が文脈から明らかだと思ったが、明確にするために、明確にするためにデータをコードに変更した。 '#define'に関して、類似性は必ずしも平等ではありませんが、私はそれを明確にするつもりです:-) – paxdiablo

1

概要

NASM 2.10.09 ELF出力:

  • dbはどんな魔法の効果を持っていない:それは単に出力オブジェクトファイルに直接バイトを出力します。

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

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

    天気あなたがdbまたはdwなどを使用しています。シンボルのサイズは指定されません。シンボルテーブルエントリのst_sizeフィールドは影響を受けません。

  • equ現在の行のシンボルのシンボルテーブルエントリには、st_shndx == SHN_ABSというマジック値があります。

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

これ以外は以下の通りです。

実際に何を意味するのかを理解するには、まずthe basics of the ELF standardrelocationを理解する必要があります。

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 

Ndxst_shndxあるので、我々はyがない間xSHN_ABSであることがわかります。

Sizeyため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閉じガスと同等のようです。

0

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 

enter image description here

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の右辺に置き換えられます。

関連する問題