我正在學習x86匯編,使用下面的代碼進行測驗,我在gdb控制臺中看到指向堆疊頂部的rsp暫存器從0x7FFFFFFFDFD0開始,如果我理解正確,在代碼中我沒有使用push或pop修改 rsp,所以 0x7FFFFFFFDFD0 它是默認值,這意味著我們在堆疊中具有相同數量的位元組,但我使用的是 linux,其中堆疊大小為 8mb
section .text
global _start
_start:
mov rcx, 2
add rcx, 8
mov rax, 0x1
mov rbx, 0xff
int 0x80
uj5u.com熱心網友回復:
對于 64 位 80x86;通常(見注 1)只能使用 48 位的虛擬地址。在不破壞舊軟體的情況下,更容易增加可用于未來處理器的位數;AMD 決定應該匹配 64 位虛擬地址中未使用的最高 16 位。符合此規定的地址稱為“規范地址”,不符合此規定的地址稱為“非規范地址”。通常(見注 2)任何訪問非規范地址的任何嘗試都會導致例外(一般保護錯誤)。
這給出了一個虛擬地址空間,如:
0x0000000000000000 to 0x00007FFFFFFFFFFF = canonical (often "user space")
0x0000800000000000 to 0xFFFF7FFFFFFFFFFF = non-canonical hole
0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFF = canonical (often "kernel space")
這使得相當明顯的是,如果沒有地址空間布局隨機化,行程的初始執行緒堆疊(參見注釋 3)開始的地址略低于行程可以使用的最高地址。
行程可以使用的最高地址與您看到的地址(0x7FFFFFFFDFD0)之間的差異僅為 2030 位元組;其中(正如 Fuz 的評論所提到的)被 ELF 輔助向量、命令列引數和環境變數之類的東西使用,它們在你的代碼啟動之前消耗了堆疊的一部分。
注 1:英特爾最近(大約 2 年前?)創建了一個擴展(如果 CPU 和作業系統支持)使 57 位虛擬地址可用。在這種情況下,“非規范漏洞”會縮小,行程可以使用的最高虛擬地址將增加到 0x00FFFFFFFFFFFFFF。
注意 2:最近(大約 6 個月前?)英特爾創建了一個擴展(如果 CPU 和作業系統支持并為行程啟用)可以使 CPU 忽略地址的未使用的高位;這樣軟體就可以將其他資訊打包到這些位中(例如,可能是“資料型別”),而無需在使用前進行顯式屏蔽。
注 3:因為作業系統通常不提供執行緒之間的隔離(例如,任何執行緒都可以破壞任何其他執行緒的堆疊或任何其他執行緒的“執行緒本地資料”);如果您創建更多執行緒,它們就不能使用相同的“堆疊頂”地址。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528226.html
