flat assembler
Message board for the users of flat assembler.

Index > Main > CPUID (not really) 80286 | Tomasz's code

Author
Thread Post new topic Reply to topic
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Tomasz wrote ( MODES.INC ) :

Code:
    mov     ax,7202h
    push    ax
  popf
        pushf        ; Unpredictable effect ???
     pop     bx
  cmp     ax,bx
       je      processor_ok ; >=80386
    


The code should find out whether CPU is 80386 or newer or below. But I
suspect that it can't work. Crying or Very sad

http://www.online.ee/~andre/i80386/Opcodes/PUSHF-PUSHFD.html

There is MUCH of such "CPUID" code around, most of it is a PUSHF/POPEF
based mess (Tomasz's is the simplest one), most of them assume to
work (or must work since in ordinary PM (80486 test only)). I found some code
that addresses the problem and tries to workaround it (in a very complicated
way, and looks buggy to me, not enough hardware to test).

Is it correct that this code will return junk when running in "V86" Crying or Very sad ?

Found also (should find out whether 80286 or newer or below):

Code:
   mov     ax,sp         
   push    sp            ; 86/186 will push sp-2
   pop     cx            ; others will push sp
   cmp     ax,cx
   je      cpu_286    ; if >=80286
    


Commenting is confusing, does "others" include 8088,80188 and NEC ? Or is this code good and safe ?

By safe I mean that it will always return "80286=false" on ALL older
CPU's lacking the SMSW instruction (8086, 8088, 80186, 80188,
NEC Vxxx, ... , and always return "80286=true" on 80286 and newer CPU's,
even when in V86 mode.

Are there other possibilities (banned instructions / methods: PUSHF/POPEF,
any interrupts, try-and-fail to brew an illegal instruction exception, CLI/STI) ? Question

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 18 Jun 2007, 05:54
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17667
Location: In your JS exploiting you and your system
revolution
The Intel doc's are quite clear about this:
Intel doc's wrote:
EFLAGS Pushed on the Stack:
8086 processor—bits 12 through 15 are always set.
Intel 286 processor—bits 12 through 15 are always cleared in real-address mode.
32-bit processors in real-address mode—bit 15 (reserved) is always cleared, and bits 12 through 14 have the last value loaded into them.
Post 18 Jun 2007, 11:13
View user's profile Send private message Visit poster's website Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Imho, why even bother with 386 detection these days? People that still run hardware that old will very likely know what they're doing.
Post 18 Jun 2007, 11:33
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
> I use this code to check if processor can execute CPUID

YES. But this was about testing 80286 against older models Confused

> The Intel doc's are quite clear about this:
> 32-bit processors in real-address mode—bit 15 (reserved) is always cleared

YES. They are very clear. Works only in real mode Crying or Very sad as said Crying or Very sad

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 19 Jun 2007, 00:16
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak
f0dder wrote:
Imho, why even bother with 386 detection these days? People that still run hardware that old will very likely know what they're doing.


Either that or they're poor.
Post 19 Jun 2007, 01:44
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
DOS386 wrote:
Is it correct that this code will return junk when running in "V86" Crying or Very sad ?

I had it tested in V86 on various machines and it was always working correctly. Note that this code has to check only whether the machine supports 32 bits, nothing more.
Post 22 Jun 2007, 07:52
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
DOS386 wrote:
YES. They are very clear. Works only in real mode Crying or Very sad as said Crying or Very sad

V86 mimics the real mode as much as possible.
Post 22 Jun 2007, 07:55
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Thanks ... but you possibly did not understand the goal of my post Confused - it was not a bug report on FASM or a request to fix ... wanted to know whether the code does have the leak and how I could do better Wink

> I had it tested in V86 on various machines and it was always working correctly.

Not really surprising.

> Note that this code has to check only whether the machine supports 32 bits, nothing more.

Sure. I know.

> V86 mimics the real mode as much as possible.

as much as or much less - obviously, it seems to work, it just happens that the PUSHF finally (after a excessive delay ?) pushes something that then evaluates to "YES we have 32-bit" - nevertheless, it is not really obligated to do - it causes a "secret" GPF and one can just hope that it will end up in correct pushing ...

Is the PUSH SP - code better / good ? I am aware that it should test for 80286 only and is not a drop-in replacement of your 80386 test.
Post 22 Jun 2007, 23:53
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
DOS386, use the above for real mode but this for pmode:

http://www.ctyme.com/intr/rb-4621.htm
http://www.delorie.com/djgpp/doc/dpmi/api/2f1687.html

In short, call int 2Fh,1687h; if that's successful (AX=0) and "TEST BX,1" is NZ (non-zero, i.e. 32-bit programs supported), and CL >= 3 (386), then you're probably on a 32-bit, Intel-compatible chip.
Post 25 Jun 2007, 01:49
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Quote:
In short, call int 2Fh,1687h


Thanks, but I know this call and does does not really do what I need Crying or Very sad

It can provide a suspect of 80286 or 80386, but NOT the evidence of 808x or 8018x Sad
Post 28 Jun 2007, 01:03
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
I forwarded you an e-mail the other day (or so I thought) about detecting such. Did you not get it? (I'm confused.) Razz

EDIT: Okay, read this:

Quote:


=======================
proper 8086 detection
=======================


SHR with values does indeed work on 80186 so you need to test for earlier CPUs first.

All later CPUs mask the CL register with 0Fh, when shifting a byte by cl bits. This test loads CL with a large value (20h) and shifts the AX register right. With the 8088, any bits in AX are shifted out, and becomes 0. On all higher level processors, the CL value of 20h is anded with 0Fh, before the shift. This means the effective number of shifts is 0, so AX is unaffected.

Code:
        mov     cl, 20h            ; load high CL value
        mov     ax, 1              ; load a non-zero value in AX
        shr     ax, cl             ; do the shift 
        cmp     ax, 0              ; if zero, then 8088/86
    


It is now either a V20/V30 or a 8088. But which one? Here's an undocumented trick: On the 8088, 0Fh performs a POP CS. On the V20/V30, it is the start of a number of multi-byte instructions. With the byte string 0Fh, 14h, C3h the CPU will perform the following:

Code:
;       8088/8086               V20/V30
        pop     cs              set1   bl, cl  
        adc     al, 0C3h 
    


So we can exploit that:

Code:
        xor     al, al             ; clear al and carry flag 
        push    cs
        db      0Fh, 14h, 0C3h     ; instructions (see above explanation)
        cmp     al, 0C3h           ; if al is C3h then 8088/8086 
        jne     upV20
        mov     ax, 0              ; set 8088/8086 flag
        jmp     Exit

upV20:
        pop     ax                 ; correct for lack of pop cs 
        mov     ax, 200h           ; set V20/V30 flag
        jmp     Exit
    


Past that, you can continue to test for the 80186: Check what is pushed onto the stack with a PUSH SP instruction. The 80186 updates the stack pointer before the value of SP is pushed onto the stack. With all higher level processors, the current value of SP is pushed onto the stack, and then the stack pointer is updated.

Code:
up186:  
        mov     bx, sp             ; save the current stack ptr 
        push    sp                 ; do test
        pop     ax                 ; get the pushed value
        cmp     ax, bx             ; did SP change ? 
        je      up286              ; if not, it's a 286+, so start
                                   ;    testing for that
        mov     ax, 1              ; set 80186 flag
        jmp     Exit 
    


Hope that helps!

Trixter
mobygamer()gmail.com

Post 28 Jun 2007, 07:06
View user's profile Send private message Visit poster's website Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
And there's also this (old, pre-Pentium Pro) file:

http://www.programmersheaven.com/download/15803/download.aspx

CPU115.ZIP wrote:

CPU/FPU Feature Detection Library
Recognizes 20+ CPUs and about 15 FPUs, checks for V86,
determines CPU clock speed and determines 386dx chip stepping.
ASM/PAS/C[++] sources included! Windows, OS/2 & DESQview-aware:
works fine in DOS box, even returning correct MHz under Windows
and DESQview! DPMI-compatible. Make batches provided.
Absolutely free of charge!!!
Post 13 Jul 2007, 00:17
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
The solution seems to exist and be simple, unfortunately nobody pointed me to it Sad

http://board.flatassembler.net/topic.php?t=7565

FASM 1.0 used to test the correct way (but failed to jump then ???) ... maybe I have correct code now ... but still no 16-bit CPU to test Sad

Tomasz wrote:

> V86 mimics the real mode as much as possible.

Intel wrote (80386 manual):

> CLTS appears in operating system software, not in application programs.
> It is a privileged instruction that can only be executed at privilege level 0.

> Flags Affected

> TS = 0 (TS is in CR0, not the flag register)

> Protected Mode Exceptions

> #GP(0) if CLTS is executed with a current privilege level other than 0

> Real Address Mode Exceptions

> None (valid in Real Address Mode to allow initialization for Protected
Mode)

> Virtual 8086 Mode Exceptions

> Same exceptions as in Real Address Mode

Either the manual is bugged or I'm stupid Sad
Post 27 Aug 2007, 21:45
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
DOS386 wrote:

FASM 1.0 used to test the correct way (but failed to jump then ???)


Tomasz didn't have ONLY8086.INC at that time. Laughing

DOS386 wrote:

maybe I have correct code now ... but still no 16-bit CPU to test Sad


Try on Joris' Retro 8086 simulator (better than nothing ... or nag Jim Leonard to test it on his 8088).
Post 29 Aug 2007, 00:40
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.