[英]What does “nop dword ptr [rax+rax]” x64 assembly instruction do?
在本頁其他地方的評論中, Michael Petch指向一個描述Intel x86多字節 NOP 操作碼的網頁。 該頁面有一個有用信息的表格,但不幸的是 HTML 亂七八糟,因此您無法閱讀。 以下是該頁面的一些信息,以及該表格呈現的可讀形式:
多字節 NOP
http://www.felixcloutier.com/x86/NOP.html
一字節的 NOP 指令是 XCHG (E)AX, (E)AX 指令的別名助記符。多字節 NOP 指令對支持的處理器不執行任何操作,並在不支持多字節 NOP 指令的處理器上產生未定義的操作碼異常。
指令的內存操作數形式允許軟件創建一個“無操作”的字節序列作為一條指令。
對於需要多字節 NOP 的情況,推薦的操作(32 位模式
和 64 位模式)是: [我的編輯:在 64 位模式下,寫rax
而不是eax
。 ]\n長度組裝字節序列\n ------- ------------------------------------------ - -------------------------\n 1 字節 nop 90\n 2 字節 66 nop 66 90\n 3 字節 nop dword ptr [eax] 0F 1F 00\n 4 字節 nop dword ptr [eax + 00h] 0F 1F 40 00\n 5 字節 nop dword ptr [eax + eax*1 + 00h] 0F 1F 44 00 00\n 6 字節 66 nop 字 ptr [eax + eax*1 + 00h] 66 0F 1F 44 00 00\n 7 字節 nop dword ptr [eax + 00000000h] 0F 1F 80 00 00 00 00\n 8 字節 nop dword ptr [eax + eax*1 + 00000000h] 0F 1F 84 00 00 00 00 00\n 9 字節 66 nop word ptr [eax + eax*1 + 00000000h] 66 0F 1F 84 00 00 00 00 00\n
請注意,選擇正確字節序列的技術——從而選擇所需的總大小——可能因您使用的匯編程序而異。
例如,從表中截取的以下兩條裝配線表面上是相似的:
nop dword ptr [eax + 00h]
nop dword ptr [eax + 00000000h]
它們僅在前導零的數量上有所不同,並且一些匯編程序可能很難禁用其始終編碼盡可能短的字節序列的“有用”功能,這可能會使第二個表達式無法訪問。
對於多字節 NOP 情況,您不需要這種“幫助”,因為您需要確保實際獲得所需的字節數。 所以問題是如何指定mod和r/m位的精確組合,最終得到所需的顯示大小——但僅通過指令助記符。 這個主題很復雜,當然超出了我的知識范圍,但Scaled Indexing 、 MOD+R/M和SIB可能是一個起點。
現在我知道你只是在想,如果你發現很難或不可能通過指令助記符來強制你的匯編程序的合作,你總是可以訴諸db
(“定義字節”)作為一個簡單的沒有大驚小怪的替代方案,嗯,保證上班。
正如評論中指出的那樣,當該指令是循環中的第一條指令時,它是一個多字節 NOP,通常用於將后續指令與 16 字節邊界對齊。
這種對齊可以幫助提高指令獲取帶寬,因為指令獲取通常以 16 字節為單位進行,因此對齊循環的頂部可以最大程度地進行解碼而不會出現瓶頸。
隨着循環緩沖區和uop 緩存的引入對對齊不那么敏感,這種對齊的重要性可以說沒有以前那么重要了。 在某些情況下,這種優化甚至可能是一種悲觀主義,尤其是當循環執行次數很少時。
當使用跳轉指令執行從較大地址到較低地址(0EBh XX - jmp short)和(0E9h XX XX XX XX - jmp near)的跳轉指令時,會完成此代碼對齊,其中 XX 在兩種情況下都是帶符號的負數。 因此,編譯器將需要執行跳轉的代碼塊對齊到 10h 字節邊界。 這將提供優化和代碼執行加速。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.