/* check whether cpuid instruction reports nx bit * 2007 lnussel@suse.d, GPL */ #include // test for cpuid instruction, from AMD processor manual static int have_cpuid() { unsigned a = 0; __asm__ __volatile__( "pushfl\n" // save EFLAGS "pop %%eax\n" // store EFLAGS in EAX "mov %%eax, %%ebx\n" // save in EBX for later testing "xor $0x200000, %%eax\n" // toggle bit 21 "push %%eax\n" // push to stack "popfl\n" // save changed EAX to EFLAGS "pushfl\n" // push EFLAGS to TOS "pop %%eax\n" // store EFLAGS in EAX "xor %%ebx, %%eax\n" // see if bit 21 has changed : "=a" (a) : : "ebx" ); return a!=0; } static int have_pae() { unsigned d = 0; __asm__ __volatile__( "movl $0x1, %%eax\n" // load cpuid function 1 "cpuid\n" : "=d" (d) : : "eax", "ebx", "ecx" ); return (d&0x40); } static int have_nx() { unsigned d = 0; __asm__ __volatile__( "movl $0x80000000, %%eax\n" // check extended functions "cpuid\n" "cmpl $0x80000000, %%eax\n" "jbe nonx\n" "movl $0x80000001, %%eax\n" "cpuid\n" "jmp out\n" "nonx:\n" "xorl %%edx, %%edx\n" "out:\n" : "=d" (d) : : "eax", "ebx", "ecx" ); return (d&(1<<20)); } int main(void) { if(!have_cpuid()) { puts("- system does not support the cpuid instruction"); return 1; } if(!have_pae()) { puts("- system does not support pae"); return 1; } if(!have_nx()) { puts("- system does not support NX"); return 1; } puts("+ NX supported"); return 0; }