Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ฮาร์ดแวร์ >> CPU

ปลดล็อคความลับของ CPU: ดึงข้อมูลระบบด้วยคำสั่ง CPUID

เมื่อพัฒนา Bootloader/Kernel การเข้าใจสถาปัตยกรรมพื้นฐานสำคัญมากสำหรับการเพิ่มประสิทธิภาพและความเข้ากันได้ระหว่างซอฟต์แวร์และฮาร์ดแวร์

คำสั่ง CPUID คืออะไร?

CPUID เป็น Low-level Instruction อยู่ในทุกตัวประมวลผล x86 และ x86-64 สมัยใหม่ ให้ซอฟต์แวร์สืบค้นข้อมูล CPU เช่น รุ่น ฟามิลี ขนาดแคช และฟีเจอร์ที่รองรับ (SIMD, Hardware Virtualization) ช่วยเพิ่มประสิทธิภาพและเปิด/ปิดฟีเจอร์ได้แบบไดนามิก

ข้อกำหนดเบื้องต้น

  • ความรู้ Assembly Language (ตัวอย่างใช้ FASM)
  • ความรู้ OS/Kernel
  • เครื่องมือ Debug Low-level (GDB) หรือ Emulator (QEMU)

ขั้นตอนที่ 1: ตรวจสอบว่า CPUID รองรับหรือไม่

ไม่ใช่ CPU ทุกตัวรองรับ CPUID ตรวจสอบโดย Toggle Bit 21 (ID Bit) ใน Register EFLAGS

cpuid_check:
  pusha           ; save state
  pushfd          ; Save EFLAGS
  pushfd          ; Store EFLAGS
  xor dword [esp], 0x00200000  ; Invert ID bit
  popfd           ; Load modified EFLAGS
  pushfd          ; Store again
  pop eax         ; eax = modified EFLAGS
  xor eax, [esp]  ; eax = changed bits
  popfd           ; Restore original EFLAGS
  and eax, 0x00200000  ; isolate ID bit
  cmp eax, 0x00
  je .cpuid_instruction_not_is_available
.cpuid_instruction_is_available:
  ; handle CPUID exists
.cpuid_instruction_not_is_available:
  ; handle CPUID not supported
.cpuid_check_end:
  popa
  ret

ดึงฟีเจอร์ของ CPU

mov eax, 0x1
cpuid

เมื่อ EAX=1 CPUID คืนค่า Bitfield ใน EDX ฟีเจอร์สำคัญ:

  • VMX, SMX: รองรับ Virtualization
  • SSE3, SSSE3, SSE4.1, SSE4.2, AVX: SIMD สำหรับมัลติมีเดีย/คณิตศาสตร์เวกเตอร์
  • AES, PCLMUL: เข้ารหัส/ถอดรหัสเร็ว
  • RDRAND: ตัวสร้างเลขสุ่มฮาร์ดแวร์
  • HTT: Hyper-Threading
  • PAE: Physical Address Extension (>4GB RAM)

ดึง Vendor String ของ CPU

mov eax, 0x0
cpuid

Vendor String อยู่ใน EBX, EDX, ECX (รวม 12 ตัวอักษร) เช่น GenuineIntel หรือ AuthenticAMD

ตัวอย่างโค้ดเต็ม: แสดง Vendor String

buffer: db 12 dup(0), 0xA, 0xD, 0

print_string:
  call print
  ret

print:
  .loop:
    lodsb
    cmp al, 0
    je .done
    call print_char
    jmp .loop
  .done:
    ret

print_char:
  mov ah, 0eh
  int 0x10
  ret

get_cpu_vendor:
  pusha
  mov eax, 0x0
  cpuid
  mov [buffer], ebx
  mov [buffer + 4], edx
  mov [buffer + 8], ecx
  mov si, buffer
  call print_string
  popa
  ret

สรุป

การเข้าใจและใช้ CPUID ทำให้ Bootloader/Kernel ปรับตัวได้ตามโปรเซสเซอร์ที่แตกต่างกัน การตรวจสอบความพร้อม และดึงข้อมูลฟีเจอร์ ขนาดแคช และเทคโนโลยีที่รองรับ จะเพิ่มประสิทธิภาพและความเข้ากันได้อย่างมาก

No