• CPUID 指令的使用


    使用 CPUID 指令可以从 processor 厂商里获得关于 processor 的详细信息,CPUID 指令是从 Intel 486 处理器以后开始加入支持。

    1. 检测处理器是否支持 cpuid 指令

    现在的处理器都支持 cpuid 指令,确实没必要去检测是否支持,除非在古老的机器上运行才有必要。

    当然,这里只是作为一个知识点介绍,在 eflags.ID 标志位是 Processor Feature Identification 位,通过修改这个标志位的值,以此来检测是否支持 cpuid 指令。

    ;-------------------------------------------------------
    ; test cpuid enable
    ;-------------------------------------------------------
            pushfd                                            ; save eflags
            mov eax, dword [esp]                              ; get old eflags
            xor dword [esp], 0x200000                         ; xor the eflags.ID value
            popfd                                             ; restore new eflags
            pushfd                                            ; save eflags again
            pop ebx                                           ; get new eflags
            cmp eax, ebx                                      ; test eflags.ID is modify
            jne support                                       ; OK! support CPUID instruction


    no_support:

            lea si, [failure_msg]
            mov ah, 0x0e
            xor bh, bh
            call printmsg

            jmp $


    support:
            ... ...

    上面这个代码能成功地修改 eflags.ID 标志位,说明 cpu 是支持 cpuid 指令的。

    2. cpuid 的使用方法

    cpuid 指令由 eax 寄存器获得输入,执行 cpuid 指令前,将功能号传给 eax 寄存器:

    输入:

    • eax

    输出:

    • eax
    • ebx
    • ecx
    • edx

    所获得的 cpu 信息返回到 eaxebxecx 以及 edx 寄存器,每一个功能所得到的信息格式是不一样的。

    mov eax, 0                   ; function 0
    cpuid

    上面代码中,将功能号 0 来获取信息,那么它将返回值是:

    • eax:最大的基本功能号
    • ebx:"Genu"
    • edx: "ineI"
    • ecx:"ntel"

    这几个字符串组合起来就是 "GenuineIntel" 对于 AMD 的处理器来说,它返回的字符串是:"AuthenticAMD"

    下面代码用来测试 CPU 的厂商是 intel 还是 amd

            mov eax, 0
            cpuid
            
    test_intel:
            cmp ecx, 0x6c65746e
            jnz test_amd
            cmp edx, 0x49656e69
            jnz test_amd
            cmp ebx, 0x756e6547
            jnz test_amd
            lea si, [vendor_intel]
            call printmsg
            jz next_do

    test_amd:
            cmp ecx, 0x444d4163        
            jnz test_other
            cmp edx, 0x69746e65
            jnz test_other
            cmp ebx, 0x68747541
            jnz test_other
            lea si, [vendor_amd]
            call printmsg
            jz next_do

    test_other:
            lea si, [vendor_other]
            call printmsg

    简单地通过直接比较 ebx, ecx 和 edx 的值来确定。

    3. 获得最大功能号

    cpuid 返回的信号包括:

    • 基本信息
    • 扩展信息

    每种信息都有 CPU 所支持的最大功能号,扩展功能号以 0x80000000 开头

            mov eax, 0                          ; get largest basic function input
            cpuid

            mov eax, 0x80000000                 ; get largest extended function input
            cpuid

    eax 寄存器返回的是 CPU 所支持的最大功能号,得到扩展最大功能号以 0x80000000 作为输入。

    4. 得到 CPU 的基本功能信息

    使用基本功能号 1 可以获得 CPU 的基本功能信息:

    • eax 返回 CPU 的家族型号等
    • ecx 和 edx 返回 CPU 的功能信息

            mov eax, 1
            cpuid
            mov esi, ecx
            mov ebx, ecx_feature_function_table
            call print_msg

    ;--------------------------------
    ; input:
    ;        esi: feature information
    ;        ebx: function table
    ;--------------------------------

    print_msg:
            xor eax, eax

    print_msg_loop:        
            cmp eax, 31
            jg print_msg_done
            
            lea edi, [ebx+eax*4]
            cmp dword [edi], 0
            jnz do_print_msg
            inc eax
            jmp print_msg_next
            
    do_print_msg:
            mov edi, [edi]
            call puts
            
            bt esi, eax
            jc print_yes
            mov edi, no
            call puts
            jmp print_msg_next
            
    print_yes:        
            mov edi, yes
            call puts

    print_msg_next:        
            inc eax
            jmp print_msg_loop
            
    print_msg_done:
            
            ret


    yes                db 'yes', 10, 0
    no                db 'no', 10, 0       

    ecx_msg:
    B0                db 'SSE3 Extension:                      ',  0
    B1                db 'Carryless Multiplication:            ',  0
    B2                db '64-bit DS Area:                      ',  0
    B3                db 'MONITOR/MWAIT:                       ',  0
    B4                db 'CPL Qualified Debug Store:           ',  0
    B5                db 'Virtual Machine Extensions:          ',  0
    B6                db 'SaferMode Extensions:                ',  0
    B7                db 'Enhanced Intel SpeedStep Technology: ',  0
    B8                db 'Thermal Monitor 2:                   ',  0
    B9                db 'SSSE3 Extensions:                    ',  0
    B10                db 'L1 Context ID:                       ',  0
    B12                db 'Fused Multiply Add:                  ',  0
    B13                db 'CMPXCHG16B:                          ',  0
    B14                db 'Update Control:                      ',  0
    B15                db 'Perf/Debug Capability MSR:           ',  0
    B17                db 'Process-context Identifiers:         ',  0
    B18                db 'Direct Cache Access:                 ',  0
    B19                db 'SSE4.1:                              ',  0
    B20                db 'SSE4.2:                              ',  0
    B21                db 'x2APIC:                              ',  0
    B22                db 'MOVEBE:                              ',  0
    B23                db 'POPCNT:                              ',  0
    B24                db 'TSC-Deadline:                        ',  0
    B25                db 'AES:                                 ',  0
    B26                db 'XSAVE:                               ',  0
    B27                db 'OSXSAVE:                             ',  0
    B28                db 'AVX:                                 ',  0


    ecx_feature_function_table:
            dd B0
            dd B1
            dd B2
            dd B3
            dd B4
            dd B5
            dd B6
            dd B7
            dd B8
            dd B9
            dd B10
            dd 0                        ; reserved
            dd B12
            dd B13
            dd B14
            dd B15
            dd 0                        ; reserved
            dd B17
            dd B18
            dd B19
            dd B20
            dd B21
            dd B22
            dd B23
            dd B24
            dd B25
            dd B26
            dd B27
            dd B28
            dd 0                        ; reserved
            dd 0                        ; reserved
            dd 0                        ; 0

    上面的代码读取 ecx,并显示出它的 feature 信息,下面是在 vmware 上的运行结果:

    上面的信息是返回在 ecx 寄存器,返回在 edx 寄存器的信息是:

    edx_msg:
    BIT0        db 'FPU:  ', 0
    BIT1        db 'VME:  ', 0
    BIT2        db 'DE:   ', 0
    BIT3        db 'PSE:  ', 0
    BIT4        db 'TSC:  ', 0
    BIT5        db 'MSR:  ', 0
    BIT6        db 'PAE:  ', 0
    BIT7        db 'MCE:  ', 0
    BIT8        db 'CMPXCHG8B: ', 0
    BIT9        db 'APIC: ', 0
    BIT11        db 'SYSENTER/SYSEXIT:', 0
    BIT12        db 'MTRR: ', 0
    BIT13        db 'PGE:  ', 0
    BIT14        db 'MCA:  ', 0
    BIT15        db 'CMOV: ', 0
    BIT16        db 'PAT:  ', 0
    BIT17        db 'PSE36:', 0
    BIT18        db 'PNS:  ', 0
    BIT19        db 'CLFSH:', 0
    BIT21        db 'Debug Store:', 0
    BIT22        db 'ACPI: ', 0
    BIT23        db 'MMX:  ', 0
    BIT24        db 'FXSR: ', 0
    BIT25        db 'SSE:  ', 0
    BIT26         db 'SSE2: ', 0
    BIT27        db 'Self snoop:', 0
    BIT28        db 'HTT:  ', 0
    BIT29        db 'TM:   ', 0
    BIT31        db 'PBE:  ', 0


    edx_feature_function_table:
            dd BIT0
            dd BIT1
            dd BIT2
            dd BIT3
            dd BIT4
            dd BIT5
            dd BIT6
            dd BIT7
            dd BIT8
            dd BIT9
            dd 0            ; reserved
            dd BIT11
            dd BIT12
            dd BIT13
            dd BIT14
            dd BIT15
            dd BIT16
            dd BIT17
            dd BIT18
            dd BIT19
            dd 0           ; reserved
            dd BIT21
            dd BIT22
            dd BIT23
            dd BIT24
            dd BIT25
            dd BIT26
            dd BIT27
            dd BIT28
            dd BIT29
            dd 0           ; reserved
            dd BIT31

    运行结果如下:


    示例代码:

    http://download.csdn.net/detail/swanabin/6969253


  • 相关阅读:
    margin和pading的百分比值
    Vue中的computed和watch
    JS的自身属性和继承属性
    JS对象的可枚举属性和不可枚举属性
    Dart语言学习
    Practice_Test
    Lesson2 basic python_20200920
    Python 基础语法L1
    小男孩和狗的故事
    智者的故事
  • 原文地址:https://www.cnblogs.com/vcerror/p/4289085.html
Copyright © 2020-2023  润新知