你的書是一種誤導,一次通過彙編,因爲大多數人會理解術語,可以通過發出稱爲重定位的特殊數據來生成可重定位的對象文件,這些數據告訴鏈接器/加載器如何重定位代碼。本書似乎使用的是「單程彙編程序」的特定定義,一個通過其自身定義不能輸出具有重定位的「可重定位目標文件」的程序。
但是,一般情況下,除非有一組重定位可用於告知什麼是可重定位或不可重定位(以及如何重定位不可重定位的指令,否則通常不能確定給定的機器代碼指令是否可重定位, T)。某些指令很明顯,例如,您可以根據目標地址的編碼方式判斷指令是否可重定位。如果目標地址被編碼爲JMP指令地址的相對偏移量,則它是可重定位的。另一方面,如果被編碼爲絕對地址,則該指令不可重定位。在第一種情況下,程序可以在不修改的情況下重新定位到內存中,並且JMP指令仍然會跳轉到相同的代碼。在第二種情況下,無論代碼已被重定位到何處,JMP指令都將跳轉到相同的地址,除非該指令被更改爲跳到正確的位置。
在x86彙編第一種情況下的具體例子是下面的:
0056: EB 10 JMP LO
指令中的第一字節,是操作碼EB
(我使用這裏的數字都是十六進制) ,它表示一個具有8位相對偏移量的近JMP指令。指令中的第二個字節是8位相對偏移量。它實際上是相對於下一條指令的開始,因此跳轉到的地址是0056 + 2 + 10
或0068
。
在6502組件第二種情況的一個例子將是:
0056: 4C 68 00 JMP LO
在這種情況下的操作碼字節4C
指具有用途在編碼到指令2字節絕對地址JMP指令。接下來的兩個字節以little-endian字節順序組成該地址:0068
。
另一個簡單的例子是類似於ADD 1,2
,它只使用寄存器。由於不涉及地址,因此指令可以在不修改的情況下進行重定位,因爲指令中沒有編碼地址。問題出在像ADD #1000,2
這樣的指令,它將字面值1000加到寄存器2中存儲的值中。在這種情況下,數字1000在指令中被編碼,並且無法知道該數字是否被用作地址或不。除了上下文之外,沒有辦法知道指令是否包含編碼地址。
在16位x86彙編語言等ADD #1000,2
一個例子是如下:
0068: 81 C3 EB 03 ADD BX, 1000
最後兩個指令EB 03
的字節是1000在十進制中的值並且是直接(文字)指令的操作數被編碼。該指令將1000添加到BX寄存器。沒有更多的背景知道1000是否應該是一個地址是不可能的。例如,代碼可能計算位於地址1000處的地址。
您可能想要查找另一本書,因爲它似乎要花費大量時間處理已過時24年的機器結構今天完全是古老的。
真的沒有什麼不同,比你的其他問題。那本書談到可重新定位的位是?那將是機器碼。對於其他指令集一般來說,是將地址加載到寄存器中,然後分支到地址,因爲它是外部地址,或者僅僅是因爲作者或編譯器是如何做到的? (vs使用電腦相對偏移量) –
我想也許你應該停止閱讀那本書。獲得一個gnu工具鏈(最好是x86,arm,mips,都是不錯的選擇),然後編譯,反彙編,然後鏈接和反彙編,思考甚至編寫你自己的工具(彙編器和鏈接器),看看問題是或可以是解決了。 –