我想計算對齊的地址。'label' 應該對齊 4 位元組邊界。
bits 32
mov eax, label
end: ; here is the end of program
align 4
label:
此 nasm 代碼輸出 8 個位元組。
$ nasm -f bin test.nasm -o test.o
$ ndisasm -o 0x0 -b 32 test.o
00000000 B808000000 mov eax,0x8
00000005 90 nop
00000006 90 nop
00000007 90 nop
但實際上程式大小是 5 個位元組。是否可以在不擴展程式大小的情況下定義標簽?我希望將“標簽”定義為值 8,而 test.o 的檔案大小將為 5。
我還嘗試使用 '$' 變數計算地址,如下所示。
bits 32
mov eax, label
end: ; here is the end of program
label equ ( ($ 3) & ~3 )
但是 nasm 不接受這種表達方式。
$ nasm -f bin test.nasm -o test.o
test.nasm:4: error: `&' operator may only be applied to scalar values
uj5u.com熱心網友回復:
這是可以預料的。的絕對地址end通常在鏈接之后才知道,因此地址的任何轉換都必須由聯結器計算。大多數系統上的聯結器可以執行一些有限的算術運算(主要是加法和減法),匯編器通過在重定位表中插入適當的條目來請求這些運算。這就是為什么您可以執行諸如mov eax, label 17或 之類的操作mov eax, label2-label1。但是它不像 那樣做完全任意的算術&,并且沒有重定位來編碼這樣的運算式。
(我想因為我們在這里輸出二進制檔案,匯編器對絕對地址有更多的了解;但它可能不是為了利用這種特殊情況而設計的。)
所以我認為你在這里不走運。您可以在 之前接受額外的填充位元組label,也可以在運行時進行對齊,例如
mov eax, label 3
and eax, ~3
uj5u.com熱心網友回復:
您應該只使用align 4。
equ在組裝時進行評估。所以它無法知道鏈接后運行時 $ 的對齊方式。此外,它給你的錯誤,
error: `&' operator may only be applied to scalar values
那是因為($ 3)不是標量值。它甚至無法在組裝時進行評估。
另一方面,align 4會將對齊要求傳遞到目標檔案中,聯結器將正確對齊標簽。如果您想驗證這是正確的,您可以檢查最終可執行檔案上的名稱串列(符號表)。
uj5u.com熱心網友回復:
正如 Nate 解釋的那樣,NASM 不會對地址進行任意數學運算,即使是在制作平面二進制檔案而不是將重定位寫入 ELF 或 COFF .o/ 時也是如此.obj。
NASM 在制作平面二進制檔案時連接部分,但不會為.bss.
這個程式組裝成你想要的 5 個位元組的機器代碼:
bits 32
mov eax, label
end: ; here is the end of program
section .bss
align 4 ; in the BSS where they don't end up in the file
label:
$ nasm -fbin foo.asm
$ ll foo
-rwxr-xr-x 1 peter peter 5 Dec 30 15:16 foo
$ ndisasm -b32 foo
00000000 B808000000 mov eax,0x8
我有點驚訝它起作用了;IDK 如果它得到官方支持或者我很幸運。
它也適用于 YASM。
在 FASM 中,即使沒有section .bss指令,它似乎也只是跳過在檔案末尾寫入對齊填充。(所以我得到了一個 6 位元組的檔案,因為我沒有為 32 位平面二進制輸出查找正確的 FASM 指令,所以它使用66運算元大小前綴來編碼mov eax, 816 位模式。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399345.html
