'Integrating x86 assembly in C++ project for old MS-DOS system information program

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.



Solution 1:[1]

In large memory model DOS programs, the default for assembly procedures is far. Removing the near keyword from the line _is_cpuid_supported proc near solved the problem. Thanks to @MichaelPetch for the tip.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sep Roland