IIRC, GetExceptionCode() is a C-thing. It requires the CRT to install an exception handler, which does the "unwinding" and calls your code. Do you really want this?
A bare exception handler in 64-bit is installed via FRAME:<exception_handler>:
;--- Win64 console application with exception handler.
;--- this variant can be assembled by both JWasm and ML64.
;--- assemble: jwasm -c Win64_5m.asm
;--- ml64 -c Win64_5m.asm
;--- link: link /subsystem:console /Libpath:\WinInc\Lib64 Win64_5m.obj
option casemap:none
includelib <msvcrt.lib>
exit proto
printf proto
;--- CStr(): macro function to simplify defining a string
CStr macro Text:VARARG
local szText
.const
szText db Text,0
.code
exitm <offset szText>
endm
EXCEPTION_MAXIMUM_PARAMETERS EQU 15
DWORD64 typedef QWORD
EXCEPTION_RECORD64 struct
ExceptionCode DWORD ?
ExceptionFlags DWORD ?
ExceptionRecord DWORD64 ?
ExceptionAddress DWORD64 ?
NumberParameters DWORD ?
__unusedAlignment DWORD ?
ExceptionInformation DWORD64 EXCEPTION_MAXIMUM_PARAMETERS dup (?)
EXCEPTION_RECORD64 ends
M128 struct
Low_ QWORD ?
High_ QWORD ?
M128 ends
LEGACY_SAVE_AREA struct
ControlWord WORD ?
Reserved0 WORD ?
StatusWord WORD ?
Reserved1 WORD ?
TagWord WORD ?
Reserved2 WORD ?
ErrorOffset DWORD ?
ErrorSelector WORD ?
ErrorOpcode WORD ?
DataOffset DWORD ?
DataSelector WORD ?
Reserved3 WORD ?
FloatRegisters BYTE 8*10 dup (?)
LEGACY_SAVE_AREA ends
CONTEXT struct
P1Home DWORD64 ?
P2Home DWORD64 ?
P3Home DWORD64 ?
P4Home DWORD64 ?
P5Home DWORD64 ?
P6Home DWORD64 ?
ContextFlags DWORD ?
MxCsr DWORD ?
SegCs WORD ?
SegDs WORD ?
SegEs WORD ?
SegFs WORD ?
SegGs WORD ?
SegSs WORD ?
EFlags DWORD ?
Dr0_ DWORD64 ?
Dr1_ DWORD64 ?
Dr2_ DWORD64 ?
Dr3_ DWORD64 ?
Dr6_ DWORD64 ?
Dr7_ DWORD64 ?
Rax_ DWORD64 ?
Rcx_ DWORD64 ?
Rdx_ DWORD64 ?
Rbx_ DWORD64 ?
Rsp_ DWORD64 ?
Rbp_ DWORD64 ?
Rsi_ DWORD64 ?
Rdi_ DWORD64 ?
R8_ DWORD64 ?
R9_ DWORD64 ?
R10_ DWORD64 ?
R11_ DWORD64 ?
R12_ DWORD64 ?
R13_ DWORD64 ?
R14_ DWORD64 ?
R15_ DWORD64 ?
Rip_ DWORD64 ?
Xmm0_ M128 <>
Xmm1_ M128 <>
Xmm2_ M128 <>
Xmm3_ M128 <>
Xmm4_ M128 <>
Xmm5_ M128 <>
Xmm6_ M128 <>
Xmm7_ M128 <>
Xmm8_ M128 <>
Xmm9_ M128 <>
Xmm10_ M128 <>
Xmm11_ M128 <>
Xmm12_ M128 <>
Xmm13_ M128 <>
Xmm14_ M128 <>
Xmm15_ M128 <>
FltSave LEGACY_SAVE_AREA <>
Fill DWORD ?
DebugControl DWORD64 ?
LastBranchToRip DWORD64 ?
LastBranchFromRip DWORD64 ?
LastExceptionToRip DWORD64 ?
LastExceptionFromRip DWORD64 ?
Fill1 DWORD64 ?
CONTEXT ends
.CODE
exchdl proc pRecord:ptr, ulframe:qword, pContext:ptr, x4:ptr
sub rsp,28h
add qword ptr [r8].CONTEXT.Rip_, 1 ;1=size of "in EAX, DX" opcode
mov edx, [rcx].EXCEPTION_RECORD64.ExceptionCode
mov rcx, CStr("exception code: %X",10)
call printf
mov eax, 0 ;0=continue execution?
add rsp,28h
ret
exchdl endp
VMwareInstalled proc FRAME:exchdl
push rbx
.pushreg rbx
.endprolog
mov eax, 0564D5868h
mov ebx, 08685D465h
mov ecx, 10
mov dx, 05658h
in eax, dx
cmp ebx, 564D5868h
setz al
movzx eax,al
add rsp,0
pop rbx
ret
VMwareInstalled endp
main proc FRAME
sub rsp,28h
.allocstack 28h
.endprolog
mov rcx, CStr("Testing VMware presence",10)
call printf
call VMwareInstalled
lea rcx, CStr("running in VMware",10)
and eax, eax
jnz @F
lea rcx, CStr("NOT running in VMware",10)
@@:
call printf
add rsp,28h
ret
main endp
mainCRTStartup proc
sub rsp,28h
call main
mov ecx,eax
call exit
mainCRTStartup endp
END