1 ;****************************************************************************
3 ;* ========================================================================
5 ;* The contents of this file are subject to the SciTech MGL Public
6 ;* License Version 1.0 (the "License"); you may not use this file
7 ;* except in compliance with the License. You may obtain a copy of
8 ;* the License at http://www.scitechsoft.com/mgl-license.txt
10 ;* Software distributed under the License is distributed on an
11 ;* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12 ;* implied. See the License for the specific language governing
13 ;* rights and limitations under the License.
15 ;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
17 ;* The Initial Developer of the Original Code is SciTech Software, Inc.
18 ;* All Rights Reserved.
20 ;* ========================================================================
22 ;* Language: NetWide Assembler (NASM) or Turbo Assembler (TASM)
23 ;* Environment: Any Intel Environment
25 ;* Description: Macros to provide memory model independant assembly language
26 ;* module for C programming. Supports the large and flat memory
29 ;* The defines that you should use when assembling modules that
30 ;* use this macro package are:
32 ;* __LARGE__ Assemble for 16-bit large model
33 ;* __FLAT__ Assemble for 32-bit FLAT memory model
34 ;* __NOU__ No underscore for all external C labels
35 ;* __NOU_VAR__ No underscore for global variables only
37 ;* The default settings are for 16-bit large memory model with
38 ;* leading underscores for symbol names.
40 ;* The main intent of the macro file is to enable programmers
41 ;* to write _one_ set of source that can be assembled to run
42 ;* in either 16 bit real and protected modes or 32 bit
43 ;* protected mode without the need to riddle the code with
44 ;* 'if flatmodel' style conditional assembly (it is still there
45 ;* but nicely hidden by a macro layer that enhances the
46 ;* readability and understandability of the resulting code).
48 ;****************************************************************************
50 ; Include the appropriate version in here depending on the assembler. NASM
51 ; appears to always try and parse code, even if it is in a non-compiling
52 ; block of a ifdef expression, and hence crashes if we include the TASM
53 ; macro package in the same header file. Hence we split the macros up into
54 ; two separate header files.
58 ;============================================================================
59 ; Macro package when compiling with NASM.
60 ;============================================================================
62 ; Turn off underscores for globals if disabled for all externals
68 ; Define the __WINDOWS__ symbol if we are compiling for any Windows
76 %define __WINDOWS32_386__ 1
79 ; Macros for accessing 'generic' registers
91 %idefine UCHAR BYTE ; Size of a character
92 %idefine USHORT WORD ; Size of a short
93 %idefine UINT DWORD ; Size of an integer
94 %idefine ULONG DWORD ; Size of a long
95 %idefine BOOL DWORD ; Size of a boolean
96 %idefine DPTR DWORD ; Size of a data pointer
97 %idefine FDPTR FWORD ; Size of a far data pointer
98 %idefine NDPTR DWORD ; Size of a near data pointer
99 %idefine CPTR DWORD ; Size of a code pointer
100 %idefine FCPTR FWORD ; Size of a far code pointer
101 %idefine NCPTR DWORD ; Size of a near code pointer
102 %idefine FPTR NEAR ; Distance for function pointers
103 %idefine DUINT dd ; Declare a integer variable
116 %idefine UCHAR BYTE ; Size of a character
117 %idefine USHORT WORD ; Size of a short
118 %idefine UINT WORD ; Size of an integer
119 %idefine ULONG DWORD ; Size of a long
120 %idefine BOOL WORD ; Size of a boolean
121 %idefine DPTR DWORD ; Size of a data pointer
122 %idefine FDPTR DWORD ; Size of a far data pointer
123 %idefine NDPTR WORD ; Size of a near data pointer
124 %idefine CPTR DWORD ; Size of a code pointer
125 %idefine FCPTR DWORD ; Size of a far code pointer
126 %idefine NCPTR WORD ; Size of a near code pointer
127 %idefine FPTR FAR ; Distance for function pointers
128 %idefine DUINT dw ; Declare a integer variable
135 ; Convert all jumps to near jumps, since NASM does not so this automatically
138 %idefine jno jno near
140 %idefine jnz jnz near
142 %idefine jne jne near
144 %idefine jbe jbe near
146 %idefine jae jae near
148 %idefine jle jle near
150 %idefine jge jge near
152 %idefine jnc jnc near
154 %idefine jns jns near
164 ; Boolean truth values (same as those in debug.h)
172 ; Macro to be invoked at the start of all modules to set up segments for
173 ; later use. Does nothing for NASM.
178 ; Macro to begin a data segment
182 segment .data public class=DATA use32 flat
185 segment _DATA public align=4 class=DATA use32 flat
187 segment _DATA public align=4 class=DATA use16
192 ; Macro to end a data segment
197 ; Macro to begin a code segment
201 segment .text public class=CODE use32 flat
204 segment _TEXT public align=16 class=CODE use32 flat
206 segment %1_TEXT public align=16 class=CODE use16
211 ; Macro to begin a near code segment
213 %imacro begcodeseg_near 0
215 segment .text public class=CODE use32 flat
218 segment _TEXT public align=16 class=CODE use32 flat
220 segment _TEXT public align=16 class=CODE use16
225 ; Macro to end a code segment
230 ; Macro to end a near code segment
232 %imacro endcodeseg_near 0
235 ; Macro for an extern C symbol. If the C compiler requires leading
236 ; underscores, then the underscores are added to the symbol names, otherwise
237 ; they are left off. The symbol name is referenced in the assembler code
238 ; using the non-underscored symbol name.
249 %imacro cexternfunc 2
258 ; Macro for a public C symbol. If the C compiler requires leading
259 ; underscores, then the underscores are added to the symbol names, otherwise
260 ; they are left off. The symbol name is referenced in the assembler code
261 ; using the non-underscored symbol name.
274 ; Macro for an global C symbol. If the C compiler requires leading
275 ; underscores, then the underscores are added to the symbol names, otherwise
276 ; they are left off. The symbol name is referenced in the assembler code
277 ; using the non-underscored symbol name.
288 ; Macro for an global C function symbol. If the C compiler requires leading
289 ; underscores, then the underscores are added to the symbol names, otherwise
290 ; they are left off. The symbol name is referenced in the assembler code
291 ; using the non-underscored symbol name.
293 %imacro cglobalfunc 1
302 ; Macro to start a C callable function. This will be a far function for
303 ; 16-bit code, and a near function for 32-bit code.
305 %imacro cprocstatic 1
315 %assign %$localsize 0
329 %assign %$localsize 0
332 ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
333 ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
334 ; rename this routine with an extra underscore with 'C' calling conventions
335 ; and a small DLL stub will be provided by the high level code to call the
338 %imacro cprocstartdll16 1
346 ; Macro to start a C callable near function.
358 %assign %$localsize 0
361 ; Macro to start a C callable far function.
373 %assign %$localsize 0
376 ; Macro to end a C function
382 ; Macros for entering and exiting C callable functions. Note that we must
383 ; always save and restore the SI and DI registers for C functions, and for
384 ; 32 bit C functions we also need to save and restore EBX and clear the
390 %ifnidn %$localsize,0
407 %ifnidn %$localsize,0
425 ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
426 ; be used in assembly routines. This evaluates to nothing in the flat memory
427 ; model, but is saves and restores DS in the large memory model.
453 ; Macros for loading the address of a data pointer into a segment and
454 ; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
455 ; memory model, or it simply loads the offset into the register in the flat
456 ; memory model since DS and ES always point to all addressable memory. You
457 ; must use the correct _REG (ie: _BX) %imacros for documentation purposes.
475 ; Macros for adding and subtracting a value from registers. Two value are
476 ; provided, one for 16 bit modes and another for 32 bit modes (the extended
477 ; register is used in 32 bit modes).
495 ; Macro to clear the high order word for the 32 bit extended registers.
496 ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
497 ; value, and will evaluate to nothing in 16 bit modes.
511 ; Macro to load an extended register with an integer value in either mode
522 ; Macros to load and store integer values with string instructions
540 ; Macros to provide resb, resw, resd compatibility with NASM
554 ; macros to declare assembler function stubs for function structures
556 %imacro BEGIN_STUBS_DEF 2
560 %define STUBS_START %1
563 %define STUBS_START _%1
570 %imacro DECLARE_STUB 1
578 jmp [DWORD STUBS_START+off]
582 %imacro DECLARE_STDCALL 2
583 %ifdef STDCALL_MANGLE
595 jmp [DWORD STUBS_START+off]
599 %imacro END_STUBS_DEF 0
603 ; macros to declare assembler import stubs for binary loadable drivers
605 %imacro BEGIN_IMPORTS_DEF 1
609 %imacro DECLARE_IMP 1
613 %imacro END_IMPORTS_DEF 0
617 else ; __NASM_MAJOR__
619 ;============================================================================
620 ; Macro package when compiling with TASM.
621 ;============================================================================
623 ; Turn off underscores for globals if disabled for all externals
629 ; Define the __WINDOWS__ symbol if we are compiling for any Windows
637 __WINDOWS32_386__ = 1
641 __WINDOWS32_386__ = 1
645 __WINDOWS32_386__ = 1
649 include vmm.inc ; IGNORE DEPEND
650 include vsegment.inc ; IGNORE DEPEND
654 ; Macros for accessing 'generic' registers
657 _ax EQU eax ; EAX is used for accumulator
658 _bx EQU ebx ; EBX is used for accumulator
659 _cx EQU ecx ; ECX is used for looping
660 _dx EQU edx ; EDX is used for data register
661 _si EQU esi ; ESI is the source index register
662 _di EQU edi ; EDI is the destination index register
663 _bp EQU ebp ; EBP is used for base pointer register
664 _sp EQU esp ; ESP is used for stack pointer register
665 _es EQU ; ES and DS are the same in 32 bit PM
666 typedef UCHAR BYTE ; Size of a character
667 typedef USHORT WORD ; Size of a short
668 typedef UINT DWORD ; Size of an integer
669 typedef ULONG DWORD ; Size of a long
670 typedef BOOL DWORD ; Size of a boolean
671 typedef DPTR DWORD ; Size of a data pointer
672 typedef FDPTR FWORD ; Size of a far data pointer
673 typedef NDPTR DWORD ; Size of a near data pointer
674 typedef CPTR DWORD ; Size of a code pointer
675 typedef FCPTR FWORD ; Size of a far code pointer
676 typedef NCPTR DWORD ; Size of a near code pointer
677 typedef DUINT DWORD ; Declare a integer variable
678 FPTR EQU NEAR ; Distance for function pointers
679 intsize = 4 ; Size of an integer
680 flatmodel = 1 ; This is a flat memory model
681 P386 ; Turn on 386 code generation
682 MODEL FLAT ; Set up for 32 bit simplified FLAT model
684 _ax EQU ax ; AX is used for accumulator
685 _bx EQU bx ; BX is used for accumulator
686 _cx EQU cx ; CX is used for looping
687 _dx EQU dx ; DX is used for data register
688 _si EQU si ; SI is the source index register
689 _di EQU di ; DI is the destination index register
690 _bp EQU bp ; BP is used for base pointer register
691 _sp EQU sp ; SP is used for stack pointer register
692 _es EQU es: ; ES is used for segment override
693 typedef UCHAR BYTE ; Size of a character
694 typedef USHORT WORD ; Size of a short
695 typedef UINT WORD ; Size of an integer
696 typedef ULONG DWORD ; Size of a long
697 typedef BOOL WORD ; Size of a boolean
698 typedef DPTR DWORD ; Size of a data pointer
699 typedef FDPTR DWORD ; Size of a far data pointer
700 typedef NDPTR WORD ; Size of a near data pointer
701 typedef CPTR DWORD ; Size of a code pointer
702 typedef FCPTR DWORD ; Size of a far code pointer
703 typedef NCPTR WORD ; Size of a near code pointer
704 typedef DUINT WORD ; Declare a integer variable
705 FPTR EQU FAR ; Distance for function pointers
706 intsize = 2 ; Size of an integer
707 P386 ; Turn on 386 code generation
711 ; Provide a typedef for real floating point numbers
721 ; Macros to access the floating point stack registers to convert them
722 ; from NASM style to TASM style
734 ; Boolean truth values (same as those in debug.h)
744 ; Macros for the _DATA data segment. This segment contains initialised data.
746 MACRO begdataseg name
755 SEGMENT _DATA DWORD PUBLIC USE16 'DATA'
760 MACRO enddataseg name
772 ; Macro for the main code segment.
774 MACRO begcodeseg name
782 ASSUME CS:FLAT,DS:FLAT,SS:FLAT
784 SEGMENT &name&_TEXT PARA PUBLIC USE16 'CODE'
785 ASSUME CS:&name&_TEXT,DS:_DATA
790 ; Macro for a near code segment
792 MACRO begcodeseg_near
795 ASSUME CS:FLAT,DS:FLAT,SS:FLAT
797 SEGMENT _TEXT PARA PUBLIC USE16 'CODE'
798 ASSUME CS:_TEXT,DS:_DATA
802 MACRO endcodeseg name
814 MACRO endcodeseg_near
820 ; Macro to be invoked at the start of all modules to set up segments for
828 ; Macro for an extern C symbol. If the C compiler requires leading
829 ; underscores, then the underscores are added to the symbol names, otherwise
830 ; they are left off. The symbol name is referenced in the assembler code
831 ; using the non-underscored symbol name.
833 MACRO cextern name,size
842 MACRO cexternfunc name,size
851 MACRO stdexternfunc name,args,size
853 EXTRN _&name&@&num_args&:size
854 name EQU _&name&@&num_args
860 ; Macro for a public C symbol. If the C compiler requires leading
861 ; underscores, then the underscores are added to the symbol names, otherwise
862 ; they are left off. The symbol name is referenced in the assembler code
863 ; using the non-underscored symbol name.
876 ; Macro for an global C symbol. If the C compiler requires leading
877 ; underscores, then the underscores are added to the symbol names, otherwise
878 ; they are left off. The symbol name is referenced in the assembler code
879 ; using the non-underscored symbol name.
890 ; Macro for an global C function symbol. If the C compiler requires leading
891 ; underscores, then the underscores are added to the symbol names, otherwise
892 ; they are left off. The symbol name is referenced in the assembler code
893 ; using the non-underscored symbol name.
895 MACRO cglobalfunc name
904 ; Macro to start a C callable function. This will be a far function for
905 ; 16-bit code, and a near function for 32-bit code.
907 MACRO cprocstatic name ; Set up model independant private proc
916 MACRO cprocstart name ; Set up model independant proc
934 MACRO cprocnear name ; Set up near proc
944 MACRO cprocfar name ; Set up far proc
954 MACRO cprocend ; End procedure macro
958 ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
959 ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
960 ; rename this routine with an extra underscore with 'C' calling conventions
961 ; and a small DLL stub will be provided by the high level code to call the
964 MACRO cprocstartdll16 name
972 ; Macros for entering and exiting C callable functions. Note that we must
973 ; always save and restore the SI and DI registers for C functions, and for
974 ; 32 bit C functions we also need to save and restore EBX and clear the
988 IFDIFI <LocalSize>,<0>
1005 IFDIFI <LocalSize>,<0>
1023 ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
1024 ; be used in assembly routines. This evaluates to nothing in the flat memory
1025 ; model, but is saves and restores DS in the large memory model.
1051 ; Macros for loading the address of a data pointer into a segment and
1052 ; index register pair. The macro explicitly loads DS or ES in the 16 bit
1053 ; memory model, or it simply loads the offset into the register in the flat
1054 ; memory model since DS and ES always point to all addressable memory. You
1055 ; must use the correct _REG (ie: _BX) macros for documentation purposes.
1057 MACRO _lds reg, addr
1065 MACRO _les reg, addr
1073 ; Macros for adding and subtracting a value from registers. Two value are
1074 ; provided, one for 16 bit modes and another for 32 bit modes (the extended
1075 ; register is used in 32 bit modes).
1077 MACRO _add reg, val16, val32
1085 MACRO _sub reg, val16, val32
1093 ; Macro to clear the high order word for the 32 bit extended registers.
1094 ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
1095 ; value, and will evaluate to nothing in 16 bit modes.
1109 ; Macro to load an extended register with an integer value in either mode
1111 MACRO loadint reg,val
1120 ; Macros to load and store integer values with string instructions
1138 ; Macros to provide resb, resw, resd compatibility with NASM
1152 ; Macros to provide resb, resw, resd compatibility with NASM
1166 ; Macros to declare assembler stubs for function structures
1168 MACRO BEGIN_STUBS_DEF name, firstOffset
1176 STUBS_START = _&name
1183 MACRO DECLARE_STUB name
1191 jmp [DWORD STUBS_START+off]
1195 MACRO DECLARE_STDCALL name,num_args
1196 ifdef STDCALL_MANGLE
1198 PUBLIC _&name&@&num_args&
1203 jmp [DWORD STUBS_START+off]
1211 MACRO BEGIN_IMPORTS_DEF name
1212 BEGIN_STUBS_DEF name,4
1215 MACRO DECLARE_IMP name
1219 MACRO END_IMPORTS_DEF