.text .equ F_ID, 0x200000 .globl _read_cpuid .globl read_cpuid _read_cpuid: read_cpuid: # determine if cpuid is available pushf pop %eax mov %eax, %edx # keep a copy of the original eflags in edx xor $F_ID, %eax push %eax popf pushf pop %eax cmp %eax, %edx jnz 0f # failed to flip ID bit, CPUID not supported mov $-1, %eax ret 0: push %ebp mov %esp, %ebp push %ebx push %edi sub $8, %esp mov 8(%ebp), %edi xor %eax, %eax mov %eax, (%esp) # current index cpuid mov %eax, (%edi) # clamp to the size of our cpuid_info structure cmp $1, %eax jbe 0f mov $1, %eax 0: mov %eax, 4(%esp) # maximum index mov %ebx, 4(%edi) mov %edx, 8(%edi) mov %ecx, 12(%edi) add $16, %edi cpuid_loop: mov (%esp), %eax inc %eax cmp 4(%esp), %eax ja cpuid_done mov %eax, (%esp) cpuid mov %eax, (%edi) mov %ebx, 4(%edi) mov %edx, 8(%edi) mov %ecx, 12(%edi) add $16, %edi jmp cpuid_loop cpuid_done: add $8, %esp pop %edi pop %ebx pop %ebp xor %eax, %eax ret