我想了解如何對x86-64中的RSP暫存器的讀數進行編碼。
例如,我有一些這樣的代碼:
.section __TEXT,__text
.global _main
_main:
push %rsp
push (%rsp)
mov %rsp, %rax
mov (%rsp), %rax
當我組裝和轉儲輸出時,它看起來像這樣:
$ as -o thing.o thing.s && objdump -d thing.o
thing.o: 檔案格式 mach-o 64-bit x86-64
反匯編部分__TEXT,__text。
0000000000000000 <add2>:
0: 54 pushq %rsp
1: ff 34 24 pushq (%rsp)
4: 48 89 e0 movq %rsp, %rax
7: 48 8b 04 24 movq (%rsp), %rax
push (%rsp)變成ff 34 24。 根據我的理解,0xFF是PUSH的操作碼,而0x34是Mod/RM的編碼。 但我不明白0x24是怎么來的。 這是SIB位元組嗎? 這條指令是如何編碼的? 我似乎不能很好地遵循英特爾的手冊來弄清楚這個位元組來自哪里。 我在mov (%rsp), %rax中看到了同樣的位元組,
uj5u.com熱心網友回復:
要對push (%rsp)進行編碼,請在指令集參考中查找push指令。你會看到它被列為FF /6。然后翻到3.1 解讀指令參考頁一章,特別是3.1.1.1 指令摘要表中的操作碼列,你會看到:
/digit 一個介于0和7之間的數字表示該指令的ModR/M位元組只使用r/m(暫存器)。 指令只使用r/m(暫存器或記憶體)運算元。暫存器 欄位包含的數字提供了對指令操作碼的擴展。 指令的操作碼的擴展。
要對(%rsp)(或[rsp] in intel語法)進行編碼,你將需要一個SIB位元組。請參考表2-2。使用ModR/M位元組的32位尋址形式。雖然它說的是32位,但它大部分也適用于64位的邏輯擴展。由于該指令有/6,請看倒數第二列,寫著[--][--]的那一行,腳注告訴你這是允許你指定一個SIB位元組。這個單元格中的值是34(十六進制),所以這就是它的來源。至于SIB位元組本身,請參考下一個表2-3。帶有SIB位元組的32位尋址形式。你需要的是標題為ESP(相當于32位的RSP)的那一列和none的那一行,它給你的是24。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/320384.html
標籤:
上一篇:在C程式中使用一個匯編函式
