I'm new to C++ programming and have always wanted to write a system information program for MS-DOS. I'm currently using the latest DigiMars C++ compiler and MASM 6.13 for my project. The project settings are for large memory model with a target CPU of an Intel 8088 processor for the widest compatibility with MS-DOS.
I'm attempting to write a routine that checks if the CPU supports the CPUID instruction found on late model 486 and early Pentium CPUs. I found a couple bits of code through Google searches and have been able to add them to the project and successfully compile, but none of them work. The problem is that when I attempt to execute the program I get a message about an invalid instruction (under my Windows NT 3.51 test system) and it completely hangs on my test MS-DOS systems.
The code I'm using is as follows:
public _is_cpuid_supported
cpuid macro
db 0fh, 0a2h
endm
_is_cpuid_supported proc near
.486
push bp
mov bp, sp
sub sp, 40
push eax
push ebx
pushfd ; get extended flags
pop eax
mov ebx, eax ; save current flags
xor eax, 200000h ; toggle bit 21
push eax ; put new flags on stack
popfd ; flags updated now in flags
pushfd ; get extended flags
pop eax
xor eax, ebx ; if bit 21 r/w then eax <> 0
pop ebx
pop eax
je no_cpuid ; can't toggle id bit 21, no cpuid here
mov ax, 1 ; cpuid supported
jmp done_cpuid_sup
no_cpuid:
mov ax, 0 ; cpuid not supported
done_cpuid_sup:
mov sp, bp
pop bp
ret
_is_cpuid_supported endp
I've also tried the sample from OSDev.org here: https://wiki.osdev.org/CPUID?msclkid=3c6e16f9c23611ec98be59859d0dd887 but it doesn't work either. Any tips? Let me know if further clarification is needed.
In
largememory model DOS programs, the default for assembly procedures isfar. Removing thenearkeyword from the line_is_cpuid_supported proc nearsolved the problem. Thanks to @MichaelPetch for the tip.