CPUID指令是一條x86架構中的的擴充指令(此處的擴充指相對i80386),其操作碼輔助記憶碼縮寫於「CPU辨識」(CPU Identification),其作用是返回特定的CPU資訊,使得軟體可以在執行時檢測CPU的硬體特性,以便於辨識並決定執行哪些代碼。首批支援CPUID指令的處理器是1993年發布的奔騰(i586)和486SL。[1]

通過使用CPUID,軟體可以確定處理器的類型和特性支援(例如MMX/SSE)。CPUID操作碼為0Fh、A2h。在呼叫CPUID前EAX暫存器內的值作為其輸入參數,Intel64指令集手冊中稱其為「葉」(Leaf),AMD64指令集手冊中稱「功能碼」(Function Number),執行CPUID後,返回值將被寫入EAX,EBX,ECX和EDX暫存器內。此外,在使用一些特殊的輸入參數時,必須同時於ECX內寫入第二個輸入參數,否則無法得到有意義的返回值。第二個參數也被稱為「子葉」(Sub Leaf)或「子功能碼」(Sub Function)。

歷史

編輯

CPUID前判斷處理器型號的方法

編輯

CPUID指令被引入前,若要在執行時確定CPU的型號,需要編寫晦澀的組合語言代碼以判斷某些指令被執行後處理器的行為。

1990年以前,對於如何判斷CPU的型號沒有官方說明與實現方法,但軟硬體工程師們總結了一套利用PUSHF/POPF指令檢測CPU行為以判斷其架構的方法。此方法在廣泛應用的同時引起了巨大爭議,反對者認為其並非萬無一失,在某些需要高可靠性的軟體平台上若處理器型號判斷錯誤,則有可能造成巨大損失,但英特爾在1990年發布了《i486微處理器程式設計師參考手冊》(i486 Microprocessor Programmer's Reference Manual Intel Corp. 1990),其中在手冊的第22.10節中使用了上述方法判斷CPU代數,並且英特爾聲稱「代碼序列已經過 Intel 驗證,可以檢測 CPUID、數學協處理器功能,並進行相應的初始化。任何其他方法都可能在未來的處理器中產生不可預測的結果」。此後該方法被應用於大多數作業系統核心中。

以下所介紹之方法為英特爾手冊中的官方演算法

該演算法的核心是利用PUSHF/POPF指令將標誌暫存器中的特定位設為1或0,並觀察處理器隨後的行為,每一代處理器的具體行為均有所不同。

8086/8088系列處理器在清除標誌暫存器的12-15位後,無論向其中寫入何值,處理器將始終把它們設為1,其檢測方式如下

        pushf                   ; 将标志寄存器内容压栈
        pop     ax              ; 将标志寄存器内容送入AX
        mov     cx, ax          ; 将标志寄存器内容送入CX备份
        and     ax, 0fffh       ; 将AX的12-15位置零
        push    ax              ; 将标志寄存器的新值压栈
        popf                    ; 送入FLAG
        pushf                   ; 获取弹栈后标志寄存器的内容
        pop     ax              ; 存入AX
        and     ax, 0f000h      ; 如果12-15位被处理器置1则为8086/8088
        cmp     ax, 0f000h     
        je      end_cpu_type_8688    ; 跳转至对应代码

對於80286系列處理器,在真實模式下這些位始終被清零,在保護模式下,其用於I/O特權級別和巢狀任務(NT),其檢測方法如下,代碼接上述代碼執行

        or      cx, 0f000h      ; 将12-15位置1
        push    cx              ; 压栈
        popf                    ; 将栈内容弹入标志寄存器
        pushf                   ; 获取标志寄存器并存入AX
        pop     ax             
        and     ax, 0f000h      ; 若12-15位位0则为286
        jz      end_cpu_type_286

檢測386/486處理器的原理與上述代碼相同,但檢測的位有所區別,486處理器中引入了一個AC標誌位,並將把它置1,其對於386而言是無效的,故386處理器將其置零,其實現如下

        pushfdEFLAGS压栈
        pop eax ;获取原始 EFLAGS 
        mov ecx, eax ;保存原来的 EFLAGS 
        xor eax, 40000h ; 翻转 EFLAGS 中的 AC 位
        push eax ;将新的 EFLAGS 压栈
        popfd 中;替换当前的 EFLAGS 
        pushfd;获取新的 EFLAGS 
        pop eax ;将新的 EFLAGS 存储在 EAX 
        xor eax, ecx 中;无法反转AC则为386
        jz end_cpu_type_386 ;如果 80386 处理器

此外,80386處理器的EDX暫存器在處理器被硬體復位後將被初始化為處理器的修訂版本號。

檢測80486奔騰(i586)

編輯

奔騰處理器支援使用CPUID指令,因此其標誌位中設定了一個被稱為ID的特殊標誌,若該標誌存在,則對應的處理器支援CPUID,檢測實現如下

        mov eax, ecx ; 获取原始 EFLAGS 
        xor eax, 200000h ;翻转 EFLAGS 中的 ID 
        push eax ;将新的 EFLAGS 值保存在堆栈
        popfd 中;替换当前的 EFLAGS 
        pushfd ;获取新的 EFLAGS 
        pop eax ;将新的 EFLAGS 存储在 EAX 
        xor eax, ecx 中;可切换则为奔腾或486SL
        jne end_cpu_type_586

關於上述方法的注意事項

編輯

該演算法無法檢測80186處理器(雖然其並未被廣泛使用),80186/88處理器包80286中包含的大部分新指令和異常,包括PUSHA/POPA、PUSH、SHL和無效操作碼異常。80186/88中唯一沒有實現的是專門用於保護模式的指令和異常。未能檢測到此處理器可能會禁止使用某些可以利用這些新指令和異常的軟體。

同時,由於PUSHF/POPF是Ring0指令,故該演算法只能在真實模式中執行,保護模式作業系統中執行的應用程式無法使用這個方法,除非處理器以及作業系統支援虛擬模式擴充(VME)。

以上演算法僅供參考與學習,在使用非英特爾處理器,完全軟體虛擬化(Full emulation)的虛擬機器或其他平台上,該演算法很有可能無法正確判斷處理器支援的指令集。考慮到奔騰已經是近30年前的處理器,除非有必要在古老的電腦上檢測CPU,否則不應該再使用這種演算法,而是直接呼叫CPUID指令。

對於非x86架構的CPU,仍然需要精心設計的代碼判斷其差別(例如使用MOVE的特權要求判斷摩托羅拉68000和68010),但大多數架構都要求具體實現者提供相應的暫存器以提供區分和判斷處理器(例如ARM64的ID_AA64暫存器)。

呼叫CPUID

編輯

CPUID 指令的操作碼是 0F A2CPUID沒有顯式的運算元,其隱式使用EAX或EAX與ECX中的值作為參數,以確定要取得的資訊。在英特爾指令集手冊中,CPUID的輸入參數(EAX),被稱為「葉」(Leaf),AMD稱其為「功能碼」(Function Number),執行CPUID後,返回值將被寫入EAX,EBX,ECX和EDX暫存器內。此外,在使用一些特殊的輸入參數時,必須同時於ECX內寫入第二個輸入參數,否則無法得到有意義的返回值。第二個參數也被稱為「子葉」(Sub Leaf)或「子功能碼」(Sub Function)。

注意,若且唯若MSR暫存器IA32_MISC_ENABLE.BOOT_NT4 的第22位為0時,EAX大於3的輸入才是有意義的。若且唯若該位被設為1時,Windows NT 4.0 SP6以前的作業系統才能正常啟動。

截止到2022年,對於一些常見的處理器架構,最大的有效的基礎輸入是0x20(GoldenCove),0x10(Zen4);最大有效的擴充輸入是0x80000008(GoldenCove),0x80000028(Zen4)。

EAX=0: 最高基礎輸入參數與製造商ID

編輯

輸入參數位0時,CPUID返回對當前處理器有意義的(即被當前架構所實現的)最大輸入參數以及ASCII編碼的製造商ID(Manufacturer ID)。

最大輸入參數被寫入EAX暫存器中,對於英特爾和AMD處理器,已知的返回值如下表所示:

英特爾處理器架構所實現的最高CPUID輸入
架構 基礎輸入 擴充輸入
80486及以前 不支援CPUID指令
486和P5 0x01 不支援
P6 0x02 不支援
P6(奔騰III) 0x03 不支援
Netbrust 0x02 0x8000 0004
Netbrust(64位元) 0x05 0x8000 0008
Core 0x0A 0x8000 0008
Core(Penryn) 0x0D 0x8000 0008
Bonnell 0x0A 0x8000 0008
Nehalem 0x0B 0x8000 0008
Sandy Bridge 0x0D 0x8000 0008
Skylake 0x16 0x8000 0008
SunnyCove 0x1B 0x8000 0008
SunnyCove(Alder Lake) 0x20 0x8000 0008
SunnyCove(Sapphire Rapids) 0x8000 0008
AMD處理器架構所實現的最高CPUID輸入
架構 基礎輸入 擴充輸入
K5以前 不支援CPUID指令
K5 0x1 不支援
K5(Krypton) 0x1 0x8000 0005
K6 0x1 0x8000 0006
K7 0x1 0x8000 0007
K8 0x1 0x8000 0018
K10 0x5 0x8000 001B
K10(Llanro) 0x6 0x8000 001B
Bulldozer 0xD 0x8000 001E
Zen 0xD 0x8000 001F
Zen2 0x10 0x8000 0020
Zen3 0x10 0x8000 0023
Zen4 0x10 0x8000 0028

製造商ID含有12個字元,以EBX-EDX-ECX的順序拼接,例如在英特爾處理器上將返回「GenuineIntel」,具體的返回值如下表所示:

暫存器 16進制值 ASCII
EBX 756E6547 Genu
ECX 6C65746E ntel
EDX 49656E69 ineI

已知的製造商以及其ID如下:

  • "AMDisbetter!" – AMD K5的早期工程樣品
  • "AuthenticAMD" – AMD
  • "CentaurHauls" – IDT/半人馬座(Centaur)/兆芯
  • "CyrixInstead" – Cyrix/意法半導體/IBM
  • "GenuineIntel" – 英特爾
  • "TransmetaCPU" – 全美達
  • "GenuineTMx86" – 全美達
  • "Geode by NSC" – 國家半導體
  • "NexGenDriven" – NexGen
  • "RiseRiseRise" – Rise
  • "SiS SiS SiS " – 矽統
  • "UMC UMC UMC " – 聯華電子(台聯電)
  • "VIA VIA VIA " – 威盛
  • "Vortex86 SoC" – DM&P Vortex86
  • "  Shanghai  " – 兆芯
  • "HygonGenuine" – 海光
  • "Genuine  RDC" – RDC
  • "E2K MACHINE" – MCST Elbrus

已知的軟核x86處理器ID:

  • "MiSTer AO486" – ao486
  • "GenuineIntel" – v586

已知的x86虛擬機器ID:

  • "bhyve bhyve " – bhyve
  • " KVMKVMKVM  "  – KVM
  • "TCGTCGTCGTCG" – QEMU
  • "Microsoft Hv" – Hyper-V
  • "MicrosoftXTA"微軟x86到ARM轉譯器
  • " lrpepyh  vr" – Parallels
  • "VMwareVMware" – VMware
  • "XenVMMXenVMM" – Xen HVM
  • "ACRNACRNACRN" – Project ACRN
  • " QNXQVMBSQG " – QNX
  • "GenuineIntel" – 蘋果 羅塞塔2 x86到ARM轉譯器
  • "VirtualApple"蘋果 羅塞塔2 x86到ARM轉譯器

使用GNU格式組合語言取得製造商ID和最高輸入的例子:

	.data

s0:	.asciz	"CPUID: %x\n"
s1:	.asciz	"Largest basic function number implemented: %i\n"
s2:	.asciz	"Vendor ID: %.12s\n"

	.text

	.align	32
	.globl	main

main:
	pushq	%rbp
	movq	%rsp,%rbp
	subq	$16,%rsp

	movl	$1,%eax
	cpuid

	leaq	s0(%rip),%rdi
	movl	%eax,%esi
	xorl	%eax,%eax
	call	printf

	pushq	%rbx

	xorl	%eax,%eax
	cpuid

	movl	%ebx,8(%rsp)
	movl	%edx,12(%rsp)
	movl	%ecx,16(%rsp)

	popq	%rbx

	leaq	s1(%rip),%rdi
	movl	%eax,%esi
	xorl	%eax,%eax
	call	printf

	leaq	s2(%rip),%rdi
	movq	%rsp,%rsi
	xorl	%eax,%eax
	call	printf

	movq	%rbp,%rsp
	popq	%rbp
//	ret
	movl	$1,%eax
	int	$0x80

EAX=1: 處理器資訊和特性

編輯

該參數在EAX中返回處理器的版本資訊,這些資訊也被稱為「簽章」(signature),一般而言,對於使用同一工藝製造的同一架構的處理器,其簽章是相同的,故該資訊可被用於判斷架構和工藝。其包含的內容以及意義如下:

EAX
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
保留=0 擴充系列號(Extended Family ID) 擴充型號(Extended Model) 保留=0 處理器類型(Type) 系列號(Family) 型號(Model) 步進(Stepping)

關於版本資訊的注意事項:

  • 若系列號部分為0xF,則實際的系列號為EAX中系列號欄位和擴充系列號欄位的和,反之實際系列號與EAX中欄位相同。
  • 若系列號部分為0xF或6,則實際的型號為EAX中擴充型號欄位左移四位後與型號欄位的和,反之實際型號與EAX中欄位相同。

上述內容用虛擬碼表示:

IF Family_ID  0FH
THEN DisplayFamily = Family_ID;
ELSE DisplayFamily = Extended_Family_ID + Family_ID;
END;
IF (Family_ID = 06H or Family_ID = 0FH)
THEN DisplayModel = (Extended_Model_ID « 4) + Model_ID;
ELSE DisplayModel = Model_ID;
END;

步進表示對處理器的修正或使用不同工藝製造,其具體意義應當參考處理器廠商所發布的手冊。

其中,處理器類型(Type)的編碼如下:

類型 二進制編碼
預設,一般OEM處理器 00
Overdrive處理器 01
雙處理器 10
保留 11

EBX中返回處理器的附加資訊,其內容被分為以下幾個欄位:

欄位 EBX 說明
7:0 處理器名稱索引號(Brand Index)
15:8 CLFLUSH指令清除快取的大小 僅當CPU支援CLFLUSH指令時

(CPUID.01.EDX.CLFSH [bit 19]= 1)有效

23:16 對於AMD處理器,若HTT標誌(位於CPUID Fn0000_0001_EDX)為1,則該欄位為該處理器的邏輯核心(即執行緒)數,反之,該欄位無意義且為0。

對於Intel處理器,若與上述相同位置的HT標誌有效,則該欄位代表該架構處理器中可定址的最大APIC ID數量,(注意:這個值不是邏輯處理器數),在奔騰4HT及以前的處理器中,該欄位代表每個物理核心對應的邏輯處理器數量。

無論是何種處理器,該欄位只在HT標誌有效時有意義。
31:24 初始Local APIC ID 該值已被x2APIC ID取代

ECX和EDX返回處理器實現的功能,一個位元代表一個功能,該位為1是表示處理器支援該功能,反之則不支援,各位對應功能或指令如下:

EDX ECX
簡稱 描述 簡稱 描述
0 fpu 整合FPU(Onboard x87 FPU) sse3 串流SIMD擴充3(SSE3或Prescott新指令(PNI))
1 vme 虛擬8086模式擴充(Virtual 8086 mode extensions) pclmulqdq PCLMULQDQ指令
2 de 除錯擴充(Debugging extensions CR4 bit 3) dtes64 64位元Debug store (edx bit 21)
3 pse 頁尺寸擴充(Page Size Extension) monitor MONITOR和MWAIT指令
4 tsc 時鐘周期計數器(Time Stamp Counter) ds-cpl CPL qualified debug store
5 msr 特殊模組暫存器(Model-Specific Registers) vmx 虛擬機器擴充(Virtual Machine eXtensions,VMX)
6 pae 實體位址擴充(Physical Address Extension) smx 安全模式擴充(Safer Mode Extensions)
7 mce 機器檢查異常(Machine Check Exception) est 增強SpeedStep(Enhanced Intel SpeedStep,EIST)
8 cx8 CMPXCHG8指令 tm2 溫度感測器2(Thermal Monitor 2)
9 apic 整合進階可程式化中斷控制器(Advanced Programmable Interrupt Controller) ssse3 串流SIMD擴充3補充指令集(Supplemental SSE3,SSSE3
10 保留 cnxt-id 一級快取上下文ID(L1 Context ID)
11 sep SYSENTER和SYSEXIT指令 sdbg Silicon Debug interface
12 mtrr 主記憶體類型範圍暫存器(Memory Type Range Registers) fma 3運算元融合乘加(Fused multiply-add 3,FMA3)
13 pge 全域分頁控制位(Page Global Enable bit in CR4) cx16 CMPXCHG16B指令
14 mca 機器檢查架構(Machine check architecture) xtpr Can disable sending task priority messages
15 cmov 條件傳送指令(CMOV) pdcm Perfmon & debug capability
16 pat 頁屬性表(Page Attribute Table) 保留
17 pse-36 36位元頁尺寸擴充(36-bit page size extension) pcid Process context identifiers (CR4 bit 17)
18 psn 處理器序列號(Processor Serial Number) dca Direct cache access for DMA writes[2][3]
19 clfsh CLFLUSH指令 sse4.1 串流SIMD擴充4.1(SSE4.1)
20 保留 sse4.2 串流SIMD擴充4.2(SSE4.2)
21 ds 除錯儲存(Debug store) x2apic x2APIC
22 acpi 整合ACPI溫控暫存器(Onboard thermal control MSRs for ACPI) movbe MOVBE指令
23 mmx 多媒體擴充(MMX popcnt POPCNT指令
24 fxsr FXSAVE,FXRESTOR 指令 tsc-deadline APIC implements one-shot operation using a TSC deadline value
25 sse 串流SIMD擴充(SSE或Katmai新指令) aes AES指令集
26 sse2 串流SIMD擴充2(SSE2 xsave XSAVE, XRESTOR, XSETBV, XGETBV指令
27 ss 自窺探快取(self-snoop cache) osxsave 作業系統啟用XSAVE
28 htt 超執行緒(Hyper-threading) avx 進階向量擴充(Advanced Vector Extensions,AVX)
29 tm 自控溫溫度感測器(Thermal monitor automatically limits temperature) f16c F16C指令集
30 ia64 基於IA64架構的處理器 rdrnd 整合亂數發生器on-chip random number generator)
31 pbe 掛起中斷(Pending Break Enable) hypervisor 當前為虛擬機器環境

EAX=2: 快取和TLB資訊(英特爾)

編輯

對於英特爾處理器,EAX=2將返回處理器快取,TLB和預取器資訊,這些資訊被編碼為數個1位元組資訊返回於EAX,EBX,ECX和EDX四個暫存器中,編碼規則如下:

EAX暫存器返回值的最低位(LSB)一定是1,它不代表任何資訊,軟體讀取時應當將其忽略。

每個暫存器返回值的最高位(MSB)代表該暫存器中的值是否有效,若MSB為0,則該暫存器包含有意義的資訊,反之則代表該暫存器為保留值且無意義。

若某一暫存器內的返回值有意義,則其應當被分割為4個等長部分,每部分長度為8為,即一位元組,每部分代表了一個快取/TLB或預取器的資訊,具體編碼見英特爾所發行的官方手冊Intel 64 and IA-32 Architectures Software Developer Manuals頁面存檔備份,存於網際網路檔案館) 卷2A中關於CPUID指令的表3-12。(截至2023.2,該表位於Vol2A,3-245到3-248頁)。

關於EAX=2的注意事項

編輯

代表快取/TLB/預取的編碼位元組沒有特定的順序,不存在「某個暫存器的某個位元組對應於哪一級別的快取」。

使用EAX=2是取得英特爾處理器快取資訊的傳統方法,但由於快取類型迅速增多,使用該方法已經無法高效的取得資訊,故對於較新的(一般認為是Core及以後)的英特爾處理器,返回值的編碼中可能包含類似0xFF或0的空描述符,對於此種情況,應當使用更新的方法(EAX=4)取得快取資訊。

對於AMD處理器,EAX=2是保留項。四個暫存器都將返回0。

EAX=3處理器序列號(英特爾)

編輯

以3作為輸入參數時,CPUID將在ECX和EDX暫存器中返回處理器序列號。

關於EAX=3的注意事項

編輯

該參數僅在使用核心代號為Katmai和Coppermine的奔騰III處理器上可用,處理器序列號是一個獨一無二的96位長的二進制數(實際只使用了64位元),每個處理器僅對應一個序列號,通過序列號可用追蹤該處理器從生產到銷售使用的全部流程,英特爾自稱引入該功能的原因是「為了提高電子商務安全性,例如只能在某台電腦上使用某張銀行卡」,但其在中美歐等多個國家和地區引起了強烈的隱私和國家安全問題爭議,民間認為該功能侵犯了使用者隱私權,居心不良者可用該功能追蹤他人的電腦,且一旦英特爾的序列號資料庫洩露,將帶來難以估量的損失,而多國的國家安全機關認為,敵對國家的情報部門可以使用該功能輕而易舉的記錄並分析電腦活動,迫於市場壓力,英特爾從核心代號Tulatin的奔騰III處理器開始禁用了這一功能,且在奔騰4以及Core處理器等後續產品上再未使用過該功能。

對於AMD處理器,EAX=3是保留項。四個暫存器都將返回0。

EAX=4快取參數(英特爾)

編輯

以4作為EAX輸入參數時,CPUID依據ECX暫存器中輸入的第二個參數(也稱為子葉)返回處理器快取資訊。

EAX返回快取類型資訊,值分為以下幾個欄位

EAX
內容 備註
4:0 快取類型 00:空

01:資料快取 10:指令快取 11:資料和指令快取

7:5 快取級別 從1開始
8 自初始化快取標誌 為1則支援自初始化,反之需要軟體初始化
9 全相聯快取標誌 同上
13:10 保留=0
25:14 最大共享此快取的執行緒數 1.指邏輯處理器,需考慮超執行緒

2.為最大值,不一定代表真實值 3.用於計算時將該欄位值+1

31:26 最大可定址的核心ID 同上

EBX,ECX返回快取尺寸資訊,返回值各個欄位如下:

EBX
內容 備註
11:0 快取線尺寸(Line Size,L) 1.以位元組為單位

2.真實值為該欄位+1

21:12 物理快取分割區數(Physical Line partitions,P) 真實值為該欄位+1
31:22 快取組行數(Ways of associativity,W) 同上

ECX返回組相聯快取的的組數(Sets,S)。

關於EAX=4的注意事項

編輯
關於子葉的意義以及最大支援的子葉
編輯

英特爾並未在其發布的官方手冊中定義子葉與快取的絕對對應關係,也未說明最大支援的子葉,上述關係表格只是軟硬體工程師的總結,但截止到2023年的SunnyCove架構,所有的英特爾處理器都遵守這一對應關係。

在面對一個全新的英特爾架構時,應當假定上述對應關係與最大子葉數不存在,並通過該指令判斷,其中對應關係由上述EAX中的返回值相應欄位確定,最大子葉值由以下方法判斷:在EAX輸入4,ECX中的初始值為0並執行CPUID指令,每次執行後將ECX內值加1,EAX仍為4,直到四個暫存器的返回值全部為0,則使返回值不為0的最大ECX輸入就是最大支援的子葉。

對於AMD處理器,EAX=3是保留項。四個暫存器都將返回0。

關於快取尺寸的計算
編輯

英特爾SDM手冊中未直接給出讀取快取尺寸的方法,但可以通過如下公式計算:

 

其中C為以位元組為單位的快取大小,W,P,L,S為讀取該快取時返回值的相應欄位。

x86外的特定CPU辨識資訊

編輯

一些非x86的CPU架構也提供了有關處理器能力的某種形式的結構化資訊,通常作為一組特殊暫存器:

  • ARM架構有一個CPUID協處理器暫存器。[4]
  • IBM System z英語IBM System z大型電腦處理器自1983年的IBM 4381英語IBM 4300起支援「Store CPU ID」(STIDP)指令[5],用於查詢處理器ID。[6]
  • MIPS32架構定義了一個強制性的Processor IdentificationPrId)和一系列菊花鏈「組態暫存器」。[7]
  • PowerPC處理器有32位元唯讀的PVR暫存器來辨識使用的處理器型號。.[8]

參見

編輯
  • CPU-Z,一個使用CPUID等資訊辨識系統組態的Windows實用工具。
  • CPU-X,一個使用CPUID等資訊辨識系統組態的Linux實用工具。
  • cpuid類Unix作業系統下的讀取CPUID的實用工具。

參考資料

編輯
  1. ^ Intel 64 and IA-32 Architectures Software Developer’s Manual (PDF). Intel.com. [2013-04-11]. (原始內容存檔 (PDF)於2009-04-19). 
  2. ^ Huggahalli, Ram; Iyer, Ravi; Tetrick, Scott. Direct Cache Access for High Bandwidth Network I/O. ACM SIGARCH Computer Architecture News. 2005, 33 (2): 50–59. doi:10.1145/1080695.1069976. CiteSeerX:10.1.1.91.957. 
  3. ^ Drepper, Ulrich, What Every Programmer Should Know About Memory, 2007, CiteSeerX:10.1.1.91.957 
  4. ^ ARM Information Center. Infocenter.arm.com. [2013-04-11]. (原始內容存檔於2013-05-27). 
  5. ^ Processor version codes and SRM constants. [2014-09-08]. (原始內容存檔於2014-09-08). 
  6. ^ IBM System z10 Enterprise Class Technical Guide (PDF). [2017-04-10]. (原始內容存檔 (PDF)於2017-08-29). 
  7. ^ MIPS32 Architecture For Programmers, Volume III: The MIPS32 Privileged Resource Architecture (PDF). MIPS Technologies, Inc. 2001-03-12 [2017-04-10]. (原始內容存檔 (PDF)於2016-03-04). 
  8. ^ PowerPC Operating Environment Architecture, book III (PDF). [2017-04-10]. (原始內容存檔 (PDF)於2016-03-04).