2016-11-15 31 views
3

在一次採訪中,有人問我是否知道x64指令的行爲因所用CPU而異,我找不到任何地方的任何文檔,是否有人知道這些指令是什麼以及爲什麼是這種情況?在不同CPU上表現不同的X64指令

+1

@PeterCordes的這個問題的答案在很大程度上取決於 「指令」 和 「CPU」 的精確定義。例如,'cpuid'是一個死牌,但在P4上它有爭議地暴露了序列號。 –

+2

目前還沒有很多公司可以烘焙x86和x64處理器芯片,AMD和Intel是唯一真正的倖存者。 x64是由AMD發明的,後來被英特爾採用。他們並不總是同意如何擴展架構,3DNow和MMX都相當死板。從他們的錯誤中吸取教訓,他們確實在用戶代碼中一起行動。但是保護模式和虛擬化,操作系統關心的東西仍然完全不同。是的,你可以很容易地回答cpuid :) –

+0

MMX是我認爲x86-64所需的基準部分,因爲x86-64需要SSE和SSE2,並且一些SSE指令在MMX寄存器上運行。所以我們可以預計CPU將永遠支持它,但即使在Skylake上,某些指令的MMX版本的吞吐量也會低於其XMM等價物。 MMX在未來CPU中的支持可能會變得更加殘缺,並且會被微碼化或者其他。 (與3DNow相比,3DNow已經死掉,大多數CPU完全不支持,甚至包括AMD的新CPU)。 –

回答

5

還有一些,即leave a register or some flags with undefined values。英特爾和AMD在那裏可能有所不同

在某些情況下,對於這些未定義的情況,實際硬件的實際行爲會保留對依賴於它的某些舊軟件的向後兼容性。例如,根據英特爾的手冊,輸入= 0時的BSF會設置ZF並使目標寄存器中的內容未定義。但是,在這種情況下,AMD的手冊(以及真正的英特爾+ AMD硬件)在沒有修改的情況下仍然保留目的地。 (這就是爲什麼bsf/具有輸出依賴性的原因。)

如果性能差異計數很多(請參閱標記wiki中的鏈接)!


你不只是在談論不受支持的說明,是嗎?像一些非常早期的x86-64 CPU在長時間模式下不支持LAHF/SAHF?或者KX早期也不支持CMPXCHG16B。

不受支持的指令最有趣的情況是LZCNT在不支持它的CPU上解碼爲REP BSR。即使對於非零輸入,它們也會返回相反的結果。 (_tzcnt_u32(x) == 31-bsr(x))。在不支持它的CPU上,TZCNT與REP BSF類似地解碼,但除了輸入= 0之外,它們執行相同的操作。我之前沒有提及過,因爲運行相同機器碼的與之不一樣運行相同的指令不同,但它聽起來像這是你要求的東西。

我們是否只談論非特權指令?特權指令的行爲可能存在更多差異。例如,Intel和AMD在SYSRET中都有不同的錯誤,以避免惡意用戶空間導致內核掛起。


另一種情況下我不知道計數:PREFETCHW Intel CPU的距離至少以酷睿2的Haswell作爲NOP運行,但在AMD的CPU(英特爾自Broadwell微架構)as an actual prefetch

因此,有些CPU會將其作爲NOP運行,有些將其作爲預取運行(因此無論哪種方式均無法在架構上顯示效果),除非在古代CPU中作爲非法insn進行故障。 64位Windows8.1 apparently requires that PREFETCHW can run without faulting(它阻止它在(某些?)64位Pentium4 CPU上運行)。

+2

除了明顯的'cpuid',你可以在'tzcnt'中執行'rep bsf'和'lzcnt'作爲CPU上的'rep bsr'

+0

我認爲這是他所說的那種指令,我們正在討論DRM,只有在特定的CPU模型上運行某種方式的代碼纔是防止共享解壓縮的二進制文件的一種方法。 – awpsoleet

+1

關於'bsf' /'bsr',AMD似乎實際上記錄瞭如果輸入爲零,即與實際的英特爾行爲一致,則寄存器不變。至少根據[本源](https://chessprogramming.wikispaces.com/BitScan#Processor%20Instructions%20for%20Bitscans-x86-Bsf/Bsr%20behavior%20with%20zero%20source)。 – BeeOnRope

3

有很多的英特爾和AMD

  • 英特爾64的BSFBSR指示行事不同於AMD64的當源是零並且操作數長度爲32位之間的差異。處理器設置零標誌並保留目標的高32位未定義。
  • Intel 64缺少一些被認爲是AMD64體系結構的MSR。這些包括SYSCFGTOP_MEMTOP_MEM2
  • 英特爾64允許SYSCALL/SYSRET僅在64位模式下(未在兼容模式),[33],並允許在兩種模式SYSENTER/SYSEXIT。[34]在長模式的兩種子模式中,AMD64缺少SYSENTER/SYSEXIT
  • 在64位模式下,具有66H(操作數大小覆蓋)前綴的分支附近行爲有所不同。英特爾64忽略此前綴:該指令具有32位符號擴展偏移量,並且指令指針不被截斷。 AMD64在指令中使用16位偏移量字段,並清除指令指針的前48位。
  • AMD處理器提高浮點數當執行80位信令NaN的FLDFSTP時,無效異常,而英特爾處理器不執行此操作。
  • 當使用SYSRET返回到非規範地址時,AMD64處理器在特權級別3執行通用保護錯誤處理程序,而在Intel 64處理器上,它在特權級別0執行。[38] [39]

https://en.wikipedia.org/wiki/X86-64#Differences_between_AMD64_and_Intel_64