This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/dm/include/macros.asm

1304 lines
21 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;_ macros.asm
; Copyright (C) 1985-1991 by Walter Bright
; All Rights Reserved
; Modified for COFF and ELF support by David Bustin
; $Revision: 1.1.1.1 $
ifdef _WIN32
ifndef __NT__
__NT__ equ 1
endif
endif
ifndef M_I386
ifdef _WINDOWS
extrn MESSAGEFATALERROR : far
endif
; modified for RATIONAL support by P Murray, April 1990
; define DOS16RM for protected mode programs
; Determine which memory model we are assembling for. For .COM files,
; force S model.
ifdef DOS16RM
ifndef I8086L
%out Only L model supported with RATIONAL DOS Extender.
end
endif
else
ifdef I8086T
I8086S equ 1
else
ifndef I8086S
ifndef I8086M
ifndef I8086C
ifndef I8086L ;if none of the memory models are defined
ifndef I8086V
I8086S equ 1 ;default to S model
endif ;I8086V
endif ;I8086L
endif ;I8086C
endif ;I8086M
endif ;I8086S
endif ;I8086T
endif ;DOS16RM
ifdef __OS2__
.286C
endif
ifdef DOS16RM
.286P
endif
ifndef I386
I386 equ 0
endif
;Decide if SI and DI are saved across function calls
SAVESIDI equ 1 ;1 means SI and DI are saved across functions
if 0 ;Lattice conventions no longer supported
MSC equ 1 ;ifdef means use Microsoft C calling conventions
;ifndef means use Lattice
endif
; Macros to bracket data segment stuff.
ifndef STARTUP
begdata macro
ifdef DOS16RM
;Segment so we can find the start of DGROUP
NULL segment para public 'BEGDATA' ;Note PARAGRAPH alignment
NULL ends
endif
_DATA segment word public 'DATA'
_DATA ends
CONST segment word public 'CONST'
CONST ends
_BSS segment word public 'BSS'
_BSS ends
ifdef DOS16RM
DGROUP group NULL,_DATA,CONST,_BSS
else
DGROUP group _DATA,CONST,_BSS
endif
_DATA segment
assume ds:DGROUP
endm
endif ; STARTUP
enddata macro
_DATA ends
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Macros specific to each memory model in an attempt to make it easier
; to write memory model independent code.
; begcode,endcode Use to bracket code sections
; P Offset on BP to first argument on stack
; (excluding any local variables)
; SPTR 1 if small data model
; LPTR 1 if large pointers (large data)
; LCODE 1 if large code model
; ESeqDS 1 if ES == DS at all times
; SSeqDS 1 if SS == DS at all times
; SIZEPTR # of bytes in a pointer
; func Declare a function as NEAR or FAR
; callm Call function as NEAR or FAR
;;;;;;;;;;;;;; SMALL MEMORY MODEL ;;;;;;;;;;;;;;;;;
ifdef I8086S
begcode macro module
_TEXT segment word public 'CODE'
assume cs:_TEXT
endm
endcode macro module
_TEXT ENDS
endm
P equ 4 ; Offset of start of parameters on the stack frame
SPTR equ 1
LPTR equ 0
LCODE equ 0
ESeqDS equ 0
SSeqDS equ 1
SIZEPTR equ 2 ; Size of a pointer
p_func macro name
name proc near
endm
p_endp macro name
name endp
endm
callp macro name
call near ptr name
endm
func macro name
_&name proc near
ifndef name
name equ _&name
endif
endm
callm macro name
call near ptr _&name
endm
endif
;;;;;;;;;;;;;;;;; MEDIUM MEMORY MODEL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ifdef I8086M
begcode macro module
module&_TEXT segment para public 'CODE'
assume cs:module&_TEXT
endm
endcode macro module
module&_TEXT ends
endm
P equ 6 ; Offset of start of parameters on the stack frame
SPTR equ 1
LPTR equ 0
LCODE equ 1
ESeqDS equ 0
SSeqDS equ 1
SIZEPTR equ 2
p_func macro name
name proc far
endm
p_endp macro name
name endp
endm
callp macro name
call far ptr name
endm
func macro name
_&name proc far
ifndef name
name equ _&name
endif
endm
callm macro name
call far ptr _&name
endm
endif
;;;;;;;;;;;;;;;;; COMPACT MEMORY MODEL ;;;;;;;;;;;;;;
ifdef I8086C
begcode macro module
_TEXT segment word public 'CODE'
assume cs:_TEXT
endm
endcode macro module
_TEXT ends
endm
P equ 4 ; Offset of start of parameters on the stack frame
SPTR equ 0
LPTR equ 1
LCODE equ 0
ESeqDS equ 0
SSeqDS equ 0
SIZEPTR equ 4
p_func macro name
name proc near
endm
p_endp macro name
name endp
endm
callp macro name
call near ptr name
endm
func macro name
_&name proc near
ifndef name
name equ _&name
endif
endm
callm macro name
call near ptr _&name
endm
endif
;;;;;;;;;;;;;;;; LARGE MEMORY MODEL ;;;;;;;;;;;;;;;;;;;
ifdef I8086L
begcode macro module
module&_TEXT segment para public 'CODE'
assume cs:module&_TEXT
endm
endcode macro module
module&_TEXT ends
endm
P equ 6 ; Offset of start of parameters on the stack frame
SPTR equ 0
LPTR equ 1
LCODE equ 1
ESeqDS equ 0
SSeqDS equ 0
SIZEPTR equ 4
p_func macro name
name proc far
endm
p_endp macro name
name endp
endm
callp macro name
call far ptr name
endm
func macro name
_&name proc far
ifndef name
name equ _&name
endif
endm
callm macro name
call far ptr _&name
endm
endif
;Macros to replace public, extrn, and endp for C-callable assembly routines,
; and to define labels: c_label defines labels,
; c_public replaces public, c_extrn replaces extrn, and c_endp replaces endp
c_name macro name
name equ _&name
endm
c_label macro name
_&name:
endm
c_public macro a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
ifnb <a> ;;Check for blank argument
public _&a
a equ _&a
ifnb <b>
c_public b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
endif
endif
endm
c_extrn macro a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
ifnb <a> ;;Check for blank argument
extrn _&a:b
a equ _&a
ifnb <c>
c_extrn c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
endif
endif
endm
c_endp macro name
_&name ENDP
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define function ctor as a static constructor
static_ctor macro ctor
if LCODE
XIFB segment word public 'DATA'
XIFB ends
XIF segment word public 'DATA'
dd ctor
XIF ends
XIFE segment word public 'DATA'
XIFE ends
else
XIB segment word public 'DATA'
XIB ends
XI segment word public 'DATA'
dw ctor
XI ends
XIE segment word public 'DATA'
XIE ends
endif
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define function ctor as a static destructor
static_dtor macro dtor
if LCODE
XCFB segment word public 'DATA'
XCFB ends
XCF segment word public 'DATA'
dd dtor
XCF ends
XCFE segment word public 'DATA'
XCFE ends
else
XCB segment word public 'DATA'
XCB ends
XC segment word public 'DATA'
dw dtor
XC ends
XCE segment word public 'DATA'
XCE ends
endif
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Other more or less useful macros
; Commented out ones are obsolete
;setESeqDS macro ;set ES == DS, if not already true
; ife ESeqDS
; push DS
; pop ES
; endif
; endm
.push macro list
irp arg,<list>
push arg
endm
endm
.pop macro list
irp arg,<list>
pop arg
endm
endm
_push macro list
irp arg,<list>
push arg
endm
endm
_pop macro list
irp arg,<list>
pop arg
endm
endm
; Macros to save and restore regs destroyed by a function
.save macro list
if SAVESIDI
irp arg,<list>
push arg
endm
endif
endm
.restore macro list
if SAVESIDI
irp arg,<list>
pop arg
endm
endif
endm
_save macro list
if SAVESIDI
irp arg,<list>
push arg
endm
endif
endm
_restore macro list
if SAVESIDI
irp arg,<list>
pop arg
endm
endif
endm
; Macros to save and restore ES, but only if ESeqDS is 1.
;pushES macro
; if ESeqDS
; push ES
; endif
; endm
;
;popES macro
; if ESeqDS
; pop ES
; endif
; endm
clr macro list ;clear a register
irp reg,<list>
xor reg,reg
endm
endm
tst macro reg
test reg,reg
endm
jmps macro lbl
jmp short lbl
endm
if @Version lt 600
;For compatibility with MASM 5.10
.if macro arg1,cond,arg2,lbl
cmp arg1,arg2
j&cond lbl
endm
endif
_if macro arg1,cond,arg2,lbl
cmp arg1,arg2
j&cond lbl
endm
;sob macro arg,lbl
; ifidn <arg>,<CX>
; loop lbl
; else
; dec arg
; jnz lbl
; endif
; endm
ifdef _WINDOWS
extrn DOS3CALL : far
endif
ifndef nobdos
bdos macro func
ifnb <func>
mov AH,func
endif
ifndef _WINDOWS
int 21h
else
call DOS3CALL
endif
endm
dpmi macro func
ifnb <func>
mov AX,func
endif
int 31h
endm
else
__bdos macro func
ifnb <func>
mov AH,func
endif
ifndef _WINDOWS
int 21h
else
call DOS3CALL
endif
endm
__dpmi macro func
ifnb <func>
mov AX,func
endif
int 31h
endm
endif
.retf macro val ;force assembler to build a far return
ifnb <val>
db 0CAh
dw val
else
db 0CBh
endif
endm
_retf macro val ;force assembler to build a far return
ifnb <val>
db 0CAh
dw val
else
db 0CBh
endif
endm
; Sometimes MASM ignores my segment overrides.
segES macro
db 26h
endm
; 32 bit negate
neg32 macro reg1,reg2
neg reg1
neg reg2
sbb reg1,0
endm
; Push immediate (reg is for scratch)
pushi macro reg,value
if 0
push value ;for 286 code generation only
else
mov reg,value
push reg
endif
endm
; Inc/dec BP if I8086V memory model
incBP macro
ifdef I8086V
inc BP
endif
endm
decBP macro
ifdef I8086V
dec BP
endif
endm
WINENTER macro
ifdef _WINDOWS
ifndef I8086S
ifndef I8086C
inc BP
endif
endif
endif
push BP
mov BP,SP
endm
WINLEAVE macro
pop BP
ifdef _WINDOWS
ifndef I8086S
ifndef I8086C
dec BP
endif
endif
endif
endm
WINENTER_NF macro
ifdef _WINDOWS
ifndef I8086S
ifndef I8086C
inc BP
push BP
mov BP,SP
endif
endif
endif
endm
WINLEAVE_NF macro
ifdef _WINDOWS
ifndef I8086S
ifndef I8086C
pop BP
dec BP
endif
endif
endif
endm
else ;M_I386
.386P
.387
ifdef DOS386
SEG_1ST_MEG equ 034h ;Selector of 1st Mbyte used by MSDOS
SEG_SCREEN equ 01ch ;Selector for the video memory.
SEG_PSP equ 024H ;PSP selector.
SEG_DGROUP equ 014H ;DGROUP selector.
SEG_ENV equ 02cH ;Selector of environment string.
OMF equ 1
COFF equ 0
ELF equ 0
_FLAT equ 0 ;FLAT memory model
_STDCALL equ 0 ;default to _stdcall
_RETST0 equ 0 ;return floating point results in ST0
endif ;DOS386
ifdef X386
_FLAT equ 0
_STDCALL equ 0
_RETST0 equ 0
endif
ifdef __OS2__
OMF equ 1
COFF equ 0
ELF equ 0
_FLAT equ 1 ;FLAT memory model
_STDCALL equ 1
_RETST0 equ 1
_INLINE_8087 equ 1 ;defined if we always generate inline 8087 code
endif
ifdef __NT__
OMF equ 1
COFF equ 0
ELF equ 0
_FLAT equ 1
_STDCALL equ 0
_RETST0 equ 1
;_NOCTOR equ 1 ;defined if no static constructors/destructors supported
_INLINE_8087 equ 1 ;defined if we always generate inline 8087 code
LONGDOUBLE equ 1 ;defined if memory model supports 80 bit long doubles
endif
ifdef M_XENIX
OMF equ 1 ;Set to non-zero if OMF object format.
COFF equ 0 ;Set to non-zero if COFF object format.
ELF equ 0
_FLAT equ 0
_STDCALL equ 0
_RETST0 equ 0
endif
ifdef M_UNIX
ifndef OMF
OMF equ 0 ;Set to non-zero if OMF object format.
endif
ifdef M_ELF
ifndef ELF
ELF equ 1 ;Set to non-zero if ELF object format.
endif
ifndef COFF
COFF equ 0 ;Set to non-zero if COFF object format.
endif
else ;M_ELF
ifndef ELF
ELF equ 0 ;Set to non-zero if ELF object format.
endif
ifndef COFF
COFF equ 1 ;Set to non-zero if COFF object format.
endif
endif ;M_ELF
_FLAT equ 0
_STDCALL equ 0
_RETST0 equ 0
endif
.ERRNZ OMF AND COFF AND ELF
.ERRE OMF OR COFF OR ELF
I386 equ 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Macros specific to each memory model in an attempt to make it easier
; to write memory model independent code.
; begcode,endcode Use to bracket code sections
; begdata,enddata Use to bracket data sections
; begrcode,endrcode Use to bracket real mode code sections
; begrdata,endrdata Use to bracket real mode data sections
; (Pharlap DOS386 only)
; P Offset on EBP to first argument on stack
; Assuming EBP was pushed.
; PS Offset on ESP to first argument on stack
; Assuming nothing was pushed on the stack.
; ESeqDS 1 if ES == DS at all times
; FSeqDS 1 if FS == DS at all times
; GSeqDS 1 if GS == DS at all times
; SSeqDS 1 if SS == DS at all times
; SIZEPTR # of bytes in a pointer
; func Declare a function as NEAR or FAR
; callm Call function as NEAR or FAR
; LPTR Large data model?
; SPTR Small data model?
;Macro for start and end of real mode code segment.
begcode_16 macro
__X386_CODESEG_16 segment para use16 public 'CODE'
assume ds:__X386_GROUP_16
assume cs:__X386_CODESEG_16
endm
endcode_16 macro
__X386_CODESEG_16 ends
endm
begcode macro module
if _FLAT
_TEXT segment para use32 public 'CODE'
assume CS:FLAT,DS:FLAT,SS:FLAT
else
_TEXT segment dword public 'CODE'
assume CS:_TEXT
endif
endm
endcode macro module
_TEXT ENDS
endm
begdata macro
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Set up segments for data
; Regular initialized data goes in _DATA
_DATA segment dword public 'DATA'
_DATA ends
ifndef _NOCTOR
;Function pointers to constructors
if OMF
XIFCB segment dword public 'DATA'
XIFCB ends
XIFU segment dword public 'DATA'
XIFU ends
XIFL segment dword public 'DATA'
XIFL ends
XIFM segment dword public 'DATA'
XIFM ends
XIFCE segment dword public 'DATA'
XIFCE ends
XIB segment dword public 'DATA'
XIB ends
XI segment dword public 'DATA'
XI ends
XIE segment dword public 'DATA'
XIE ends
;Function pointers to destructors
XCB segment dword public 'DATA'
XCB ends
XC segment dword public 'DATA'
XC ends
XCE segment dword public 'DATA'
XCE ends
;Constant data, such as switch tables, go here.
CONST segment dword public 'CONST'
CONST ends
endif
;Segment for uninitialized data. This is set to 0 by the startup code/OS,
;so it does not consume room in the executable file.
_BSS segment dword public 'BSS'
_BSS ends
if OMF
;Function pointers to destructors
XOB segment dword public 'BSS'
XOB ends
XO segment dword public 'BSS'
XO ends
XOE segment dword public 'BSS'
XOE ends
endif
if OMF
ifdef DOS386
HUGE_BSS segment dword public 'HUGE_BSS'
HUGE_BSS ends
endif
EEND segment dword public 'ENDBSS'
EEND ends
ifdef DOS386
STACK segment para stack 'STACK'
STACK ends
DGROUP group _DATA,XIFCB,XIFU,XIFL,XIFM,XIFCE,XOB,XO,XOE,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS,EEND,STACK
else
ifdef __OS2__
STACK segment para stack 'STACK'
STACK ends
DGROUP group _DATA,XIFCB,XIFU,XIFL,XIFM,XIFCE,XOB,XO,XOE,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS,EEND,STACK
else
ifdef __NT__
STACK segment para stack 'STACK'
STACK ends
DGROUP group _DATA,XIFCB,XIFU,XIFL,XIFM,XIFCE,XOB,XO,XOE,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS,EEND,STACK
else
DGROUP group _DATA,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS,EEND
endif ;__NT__
endif ;__OS2__
endif ;DOS386
else ;OMF
if OMF
DGROUP group _DATA,XIFCB,XIFU,XIFL,XIFM,XIFCE,XOB,XO,XOE,XIB,XI,XIE,XCB,XC,XCE,CONST,_BSS
else
DGROUP group _DATA,_BSS
endif
endif
endif
_DATA segment
if _FLAT
assume DS:FLAT
else
assume DS:DGROUP
endif
endm
enddata macro
_DATA ends
endm
P equ 8 ; Offset of start of parameters on the stack frame
; From EBP assuming EBP was pushed.
PS equ 4 ; Offset of start of parameters on the stack frame
; From ESP assuming EBP was NOT pushed.
;; For Win32, ESeqDS should be TRUE
ifdef _WIN32
ESeqDS equ 1
else
ESeqDS equ 0
endif
FSeqDS equ 0
GSeqDS equ 0
SSeqDS equ 1
SIZEPTR equ 4 ; Size of a pointer
LPTR equ 0
SPTR equ 1
LCODE equ 0
func macro name
_&name proc near
ifndef name
name equ _&name
endif
endm
callm macro name
call _&name
endm
;Macros to replace public, extrn, and endp for C-callable assembly routines,
; and to define labels: c_label defines labels,
; c_public replaces public, c_extrn replaces extrn, and c_endp replaces endp
c_name macro name
name equ _&name
endm
c_label macro name
_&name:
endm
c_public macro a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
ifnb <a> ;;Check for blank argument
public _&a
a equ _&a
ifnb <b>
c_public b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
endif
endif
endm
c_extrn macro a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
ifnb <a> ;;Check for blank argument
extrn _&a:b
a equ _&a
ifnb <c>
c_extrn c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
endif
endif
endm
c_endp macro name
_&name ENDP
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define function ctor as a static constructor
static_ctor macro ctor
ifndef _NOCTOR
if 1
XIFCB segment dword public 'DATA'
XIFCB ends
XIFU segment dword public 'DATA'
;dd ctor
XIFU ends
XIFL segment dword public 'DATA'
;dd ctor
XIFL ends
XIFM segment dword public 'DATA'
if _FLAT
dd offset FLAT:ctor
else
dd ctor
endif
XIFM ends
XIFCE segment dword public 'DATA'
XIFCE ends
else
XIB segment dword public 'DATA'
XIB ends
XI segment dword public 'DATA'
if _FLAT
dd offset FLAT:ctor
else
dd ctor
endif
XI ends
XIE segment dword public 'DATA'
XIE ends
endif
endif
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define function dtor as a static destructor
static_dtor macro dtor
ifndef _NOCTOR
if 1
XOB segment dword public 'DATA'
XOB ends
XO segment dword public 'DATA'
if _FLAT
dd offset FLAT:dtor
else
dd dtor
endif
XO ends
XOE segment dword public 'DATA'
XOE ends
else
XCB segment dword public 'DATA'
XCB ends
XC segment dword public 'DATA'
if _FLAT
dd offset FLAT:dtor
else
dd dtor
endif
XC ends
XCE segment dword public 'DATA'
XCE ends
endif
endif
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Other more or less useful macros
;Aligns the code on dword boundary for max speed.
_align macro
;MASM 6.0 has a bug where ALIGN 4 produces bogus code when
;2 or 3 bytes of filler are necessary.
ifdef @Version
if @Version eq 600
if 0
if (($ - _TEXT) and 3) eq 1
db 08Bh,0C0h ;MOV EAX,EAX
nop
else
if (($ - _TEXT) and 3) eq 2
db 08Bh,0C0h ;MOV EAX,EAX
else
if (($ - _TEXT) and 3) eq 3
nop
endif
endif
endif
endif
else
align 4 ;for MASM 5.1
endif
else
align 4 ;for 386ASM
endif
endm
_push macro list
irp arg,<list>
push arg
endm
endm
_pop macro list
irp arg,<list>
pop arg
endm
endm
_if macro arg1,cond,arg2,lbl
cmp arg1,arg2
j&cond lbl
endm
_ifs macro arg1,cond,arg2,lbl
cmp arg1,arg2
j&cond short lbl
endm
clr macro list ;clear a register
irp reg,<list>
xor reg,reg
endm
endm
jmps macro lbl
jmp short lbl
endm
tst macro reg
test reg,reg
endm
ifndef nobdos
ifdef DOS386
bdos macro func ;DOS system call.
ifnb <func>
mov AH,func
endif
int 21h
endm
endif ;DOS386
ifdef X386
bdos macro func ;DOS system call.
ifnb <func>
mov AH,func
endif
int 21h
endm
endif ;DOS386
ifdef M_XENIX
bdos macro func ; 386 XENIX system call.
ifnb <func>
mov EAX,func
endif
db 9ah ; call far 0x7:0
dd 0
dw 07h
endm
endif ;M_XENIX
ifdef M_UNIX
bdos macro func ; UNIX system call.
ifnb <func>
mov EAX,func
endif
db 9ah ; call far 0x7:0
dd 0
dw 07h
endm
endif ;M_UNIX
endif ;nobdos
_retf macro val ;force assembler to build a far return
ifnb <val>
db 0CAh
dw val
else
db 0CBh
endif
endm
_ret macro val ;decide whether caller or callee cleans stack
if _STDCALL
ret val
else
ret
endif
endm
; Macros to save and restore regs destroyed by a function
; Give the macro the list of registers used by the function:
; uses <AX,BX,SI,DI>
;
; At exit to function use 'unuse':
; unuse <DI,SI,BX,AX>
uses macro list
irp reg,<list>
ifidn <reg>,<ebx> ;Save ebx.
push reg
endif
ifidn <reg>,<EBX> ;Save EBX (bug in ifidni).
push reg
endif
ifidn <reg>,<esi> ;Save esi.
push reg
endif
ifidn <reg>,<ESI>
push reg
endif
ifidn <reg>,<edi> ;Save edi.
push reg
endif
ifidn <reg>,<EDI>
push reg
endif
ifidn <reg>,<bx> ;Save bx.
push reg
endif
ifidn <reg>,<BX>
push reg
endif
ifidn <reg>,<si> ;Save si.
push reg
endif
ifidn <reg>,<SI>
push reg
endif
ifidn <reg>,<di> ;Save di.
push reg
endif
ifidn <reg>,<DI>
push reg
endif
ifidn <reg>,<ds> ;Save ds.
push reg
endif
ifidn <reg>,<DS>
push reg
endif
ifidn <reg>,<es> ;Save es.
push reg
endif
ifidn <reg>,<ES>
push reg
endif
endm
endm
unuse macro list
irp reg,<list>
ifidn <reg>,<ebx> ;Restore ebx.
pop reg
endif
ifidn <reg>,<EBX>
pop reg
endif
ifidn <reg>,<esi> ;Restore esi.
pop reg
endif
ifidn <reg>,<ESI>
pop reg
endif
ifidn <reg>,<edi> ;Restore edi.
pop reg
endif
ifidn <reg>,<EDI>
pop reg
endif
ifidn <reg>,<bx> ;Restore bx.
pop reg
endif
ifidn <reg>,<BX>
pop reg
endif
ifidn <reg>,<si> ;Restore si.
pop reg
endif
ifidn <reg>,<SI>
pop reg
endif
ifidn <reg>,<di> ;Restore di.
pop reg
endif
ifidn <reg>,<DI>
pop reg
endif
ifidn <reg>,<ds> ;Restore ds.
pop reg
endif
ifidn <reg>,<DS>
pop reg
endif
ifidn <reg>,<es> ;Restore es.
pop reg
endif
ifidn <reg>,<ES>
pop reg
endif
endm
endm
endif ;M_I386
; Executable type
EXE_DOS equ 1 ; MSDOS
EXE_DOS16RM equ 2 ; Rational 286 DOS Extender
EXE_ZPM equ 4 ; ZPM 286 DOS Extender
EXE_PHAR386 equ 8 ; Pharlap 386 DOS Extender
EXE_DOSX equ 010h ; DOSX 386 DOS Extender
EXE_WINDOWS equ 020h ; Windows 3
EXE_OS2 equ 040h ; OS/2 1.x
EXE_SCOUNIX equ 080h ; SCO Unix
EXE_OS2_2 equ 100h ; OS/2 2.0
EXE_WINDOWSNT equ 200h ; Windows NT