回答
首先是equate
,類似於C的:
#define len 2
在於它實際上不分配在最終代碼的任何空間,它簡單地設置len
符號爲等於2。然後,當稍後在源代碼中使用len
,與使用常量2
的情況相同。
第二是define byte
,類似於C的:
int len = 2;
它並實際分配空間,在存儲器中的一個字節,存儲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行中,沒有生成代碼,彙編器僅將elen
加載到符號表中,其值爲2
。由於沒有生成代碼,所以地址不會改變。
然後,當您在第4行使用它時,它會將該值加載到寄存器中。
第3行顯示db
不同,它實際上分配了一些空間(一個字節)並將該值存儲在該空間中。然後它將dlen
加載到符號表中,但給它的值是地址1234
而不是常量值2
。
當您稍後在第5行使用dlen
時,會得到地址,您將不得不解除引用以獲取實際值2
。
摘要
NASM 09年2月10日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符號的符號是內存地址,因此必須經過重定位。
由於它不指向內存,因此可以通過內聯將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
包含一個字面值,無解引用[]
必須做它像y
。
如果我們想用x
從C程序,我們需要這樣的:
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
,所以我們看到x
是SHN_ABS
而y
不是。
也看到Size
是0
爲y
:db
絕不告訴y
這是一個單字節寬。我們可以簡單地添加兩個db
指令來在那裏分配2個字節。
然後:
objdump -dr equ
給出:
08048080 <_start>:
8048080: b0 01 mov $0x1,%al
8048082: a0 88 90 04 08 mov 0x8049088,%al
所以我們看到,0x1
被聯到指令,而y
得到了搬遷地址0x8049088
的價值。
在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節的解釋$)計算一次,而不是在被引用的任何地方評估,並使用$在參考點。
也
類似的問題,請參見氣:Difference between .equ and .word in ARM Assembly?.equiv
似乎是關閉油氣當量。
equ:預處理器時間。類似於#define,但大多數彙編程序缺少#undef,除了右邊的固定字節數的原子常量外,其他所有彙編程序的equ指令都不支持浮點,雙精度和列表。
db:編譯時間。存儲在db中的值以彙編器的特定偏移量存儲在二進制輸出中。 equ允許你定義通常需要硬編碼的常量,或者需要mov操作才能得到。 db允許你在程序啓動之前在內存中有數據。
這裏有一個NASM示範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的
例如,一些常見的限制沿的。
; 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不污染圖像;所有對等式的引用都被該等式的右邊替換。
- 1. NASM中的%define和equ有什麼區別?
- 2. MIPS中.word和.equ有什麼區別?
- 3. NoSql DB和OO Db有什麼區別?
- 4. .sqlite和.db文件有什麼區別?
- 5. 有什麼區別`和$(Bash中有什麼區別?
- 6. 在perl中,$ DB :: single = 1和2有什麼區別?
- 7. 在Mongo DB中保存和插入有什麼區別?
- 8. MASM shellcode和NASM shellcode是否有區別
- 9. 在mysql複製過程中'replicate-rewrite-db'和'replicate-do-db'有什麼區別?
- 10. 有什麼區別? :和||
- 11. &&和||有什麼區別?
- 12. 「/」和「/ *」有什麼區別?
- 13. 有什麼區別:。!和:r!?
- 14. ==和===有什麼區別?
- 15. Appender和〜有什麼區別?
- 16. $ @和$ *有什麼區別?
- 17. is和=有什麼區別?
- 18. #.00和#。##有什麼區別?
- 19. `==`和`is`有什麼區別?
- 20. '=='和'==='有什麼區別?
- 21. /和/#/有什麼區別?
- 22. | 0和~~有什麼區別?
- 23. `&`和`ref`有什麼區別?
- 24. ==和===有什麼區別?
- 25. ==和===有什麼區別?
- 26. `{}`和`[]`有什麼區別?
- 27. JavaScript和=== ===有什麼區別?
- 28. difftime和' - '有什麼區別?
- 29. =和==有什麼區別?
- 30. 這些nasm堆棧推動之間有什麼區別?
NASM 2.10.09 ELF輸出nitpicks:1)「沒有數據產生」:鏈接和RAM空間後,可執行文件爲true,但NASM生成的目標文件包含符號數據。 2)「類似於C的#define」:從某種意義上說,「equ」確實生成了一個符號,它可以被其他具有「extern」的目標文件使用,並且不會在這些文件中包含宏。更多細節:http://stackoverflow.com/a/33148242/895245 –
好點,@Ciro,我認爲從上下文中可以明顯地看出其含義,但爲了確定,我已將數據更改爲代碼以確保清晰。至於'#define',相似性不一定是平等的,但我會盡力澄清:-) – paxdiablo