我試圖了解組裝和鏈接是如何作業的,所以我有一個使用 NASM 生成的串列檔案,我正在徘徊括號([])的含義,這是一種告訴它它可能會改變的可重新分配地址的方法鏈接階段?
編輯:我正在使用這個 .lst 檔案nasm -f obj
1 segment data public
2 00000000 4141414141414141 db 8 dup ('A')
3 segment code public
4 ..start:
5 00000000 B8[ssss] mov ax,data
6 00000003 B8[0300] mov ax,$
7 00000006 B8[0000] mov ax,..start
8 00000009 B80002 mov ax,200h
9 0000000C EBFE jmp $
uj5u.com熱心網友回復:
NASM 用方括號[]或圓括號()裝飾串列轉儲中的可重定位值。這通常表明括號中的值可能與鏈接程式中的值不同,這可以在運行時在除錯器中看到。匯編器不知道如何將來自其他單獨組裝的模塊的代碼和資料在鏈接時連接在一起。它也不知道在運行時將加載代碼和資料的地址,因此它假定所有段都從地址0開始。絕對重定位(由[ ]標記)指定括號中的值(偏移量)需要增加以匹配運行時的最終地址。
在您的 16 位示例中,僅當您的程式將與也定義 的其他模塊鏈接時,此差異才適用segment code public,并且如果該其他模塊先行,從而提高了code段中的組裝偏移量。否則,第 6 行和第 7 行的偏移量在鏈接時間之后有效,并且這些指令將被編碼為B80300最終B80000可執行檔案(不會應用重定位)。
指令JMPN和CALLN編碼目標地址相對于下一條指令的地址(保存在指令指標暫存器中),所以稱為RIP 相對尋址。當對同一段執行 NEARJMP或時CALL,匯編程式能夠立即計算差異,并且不需要重定位。但是,我們也可以從其他單獨組裝的模塊中呼叫某些程序。雖然這個程序也可能在 中segment code public,它會和主code段連接在一起,但是匯編器不知道段的最終布局,所以它必須擴展相對重定位請求,并在編碼中裝飾立即值CALLN帶括號( )。
第 5 行是一個不同的野獸:它編碼段的第一個位元組的段地址data,而不是它的偏移量。這就是為什么 NASM 顯示段落地址[ssss]而不是,[0000]并且這個值肯定不是零 - 它取決于 DOS 將加載可執行程式的地址。用,
初始化段暫存器并不是需要段重定位的唯一情況,它用于每個和指令的編碼。指向段部分和編碼的遠指標收集在 DOS 可執行檔案中 MZ 標頭之后(所謂的重定位條目),它們用于修改mov ax,datamov ds,axJMPFCALLFJMPFCALLFFAR 指令的段部分和加載時存盤的 FAR 指標。
其他匯編程式可能會在串列中以不同的方式表示重定位,
例如€ASM使用[ ]、( )和{ }來區分絕對、RIP 相對和段地址重定位。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/468269.html
