I wonder if someone could share shorter way
to check for CPUID support.
Now I'm checking this way:


mov eax,sbit(21) ;macro to generate value power of 2
pushfd
xor [esp],eax
popfd
pushfd
test [esp],eax
je @nocpuid
xor [esp],eax
;cpuid OK
popfd
.....

@nocpuid:
popfd
....
Posted on 2003-03-13 06:53:35 by The Svin
I found this somewhere on the net:



pushfd ; push eflags
pop eax ; move to eflags to aex
mov edx,eax ; make a copy
xor eax,200000h ; toggle the bit
push eax ; push copy of eflags
popfd ; check if CPUID flag could toggle
pushfd ; save it, so we can check it
pop eax ; get it
xor eax,edx ; did bit toggle?
jz end_label ; can't use CPUID instruction
; can use CPUID instruction
end_label:
push edx ; push origianl copy of EFLAGS
popfd ; restore original EFLAGS value
Posted on 2003-03-13 07:34:43 by bazik
Thanks for replay.
The same size and IMHO bad disign to use edx for storing EFL, 'cause
if CPUID if OK then after check there would be most likely CPUID instruction
that would spoil edx, so edx needs additional presevation with EFL values.
Another try - more instructions but less in size:


pushfd ;1
mov eax,sbit(21);5
pushfd ;1
pop ecx ;1
xor ecx,eax;2
push ecx;1
popfd ;1
pushfd;1
pop ecx ;1
test ecx,eax ;2
popfd ;1
je @nocpuid
;here is code for cpuid
....
@nocpuid:
;code in case of absence of CPUID
Posted on 2003-03-13 08:21:17 by The Svin
just in case - here is sbit macro


;-------------------
sbit macro bitnum
;-------------------
LOCAL p2
p2=1
rept bitnum
p2=p2+p2
endm
exitm %p2
endm
Posted on 2003-03-13 08:54:54 by The Svin
Why write a macro for that, when there is one built in?

1 SHL 21

Mirno
Posted on 2003-03-13 17:01:13 by Mirno
It's matter of personal taste.
sbit wasn't written for this particular case.
I prefer see syntax that stress what is important to me,
not expression with the same result but less clear.
Let me give you example
I need load value that contains bit 30 and 7 set
I could write:
push (1 shl 30) or (1 shl 7)
the other way I could write:
push sbit(30) or sbit(7)
Last one more compehencive to me in regard of what it means
when I look at source.
Posted on 2003-03-13 17:48:58 by The Svin
Stupid idea: how 'bout SEH?

But aren't we at the point yet where we can assume >= late 486 CPUs? :)
Posted on 2003-03-14 11:59:10 by Jan Wassenberg
How about this?



pushfd ; 1
or byte [esp+2],32 ; 5
popfd ; 1
pushfd ; 1
pop eax ; 1
shr eax,22 ; 3
jae no_cpuid ; 2
; ...
no_cpuid:
Posted on 2003-03-15 17:01:13 by Sephiroth3
Sephiroth3,
That's good one :)
I'd choose jnc mnemonic for clarity
Posted on 2003-03-16 07:20:31 by The Svin
About size calculation,
1. About jcc - I treat is as x not as 2, 'cause it's not clear how
long block working with "cpuid ok " could be. And so I don't count it at all
in all versions.
2. I would like make sure that EFL restored, so I'd add 2 bytes
for restoring EFL.

Alltogether with the correction it makes 14 bytes wich is 3 bytes
shorter than my last version. Good result.
Posted on 2003-03-16 08:32:24 by The Svin