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
202 extern _GLOBAL_OFFSET_TABLE_
204 extern __GLOBAL_OFFSET_TABLE_
208 segment .text public class=CODE use32 flat
211 segment _TEXT public align=16 class=CODE use32 flat
213 segment %1_TEXT public align=16 class=CODE use16
218 ; Macro to begin a near code segment
220 %imacro begcodeseg_near 0
222 segment .text public class=CODE use32 flat
225 segment _TEXT public align=16 class=CODE use32 flat
227 segment _TEXT public align=16 class=CODE use16
232 ; Macro to end a code segment
237 ; Macro to end a near code segment
239 %imacro endcodeseg_near 0
242 ; Macro for an extern C symbol. If the C compiler requires leading
243 ; underscores, then the underscores are added to the symbol names, otherwise
244 ; they are left off. The symbol name is referenced in the assembler code
245 ; using the non-underscored symbol name.
256 %imacro cexternfunc 2
265 ; Macro for a public C symbol. If the C compiler requires leading
266 ; underscores, then the underscores are added to the symbol names, otherwise
267 ; they are left off. The symbol name is referenced in the assembler code
268 ; using the non-underscored symbol name.
281 ; Macro for an global C symbol. If the C compiler requires leading
282 ; underscores, then the underscores are added to the symbol names, otherwise
283 ; they are left off. The symbol name is referenced in the assembler code
284 ; using the non-underscored symbol name.
295 ; Macro for an global C function symbol. If the C compiler requires leading
296 ; underscores, then the underscores are added to the symbol names, otherwise
297 ; they are left off. The symbol name is referenced in the assembler code
298 ; using the non-underscored symbol name.
300 %imacro cglobalfunc 1
313 ; Macro to start a C callable function. This will be a far function for
314 ; 16-bit code, and a near function for 32-bit code.
316 %imacro cprocstatic 1
326 %assign %$localsize 0
340 %assign %$localsize 0
343 ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
344 ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
345 ; rename this routine with an extra underscore with 'C' calling conventions
346 ; and a small DLL stub will be provided by the high level code to call the
349 %imacro cprocstartdll16 1
357 ; Macro to start a C callable near function.
369 %assign %$localsize 0
372 ; Macro to start a C callable far function.
384 %assign %$localsize 0
387 ; Macro to end a C function
393 ; Macros for entering and exiting C callable functions. Note that we must
394 ; always save and restore the SI and DI registers for C functions, and for
395 ; 32 bit C functions we also need to save and restore EBX and clear the
401 %ifnidn %$localsize,0
418 %ifnidn %$localsize,0
436 ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
437 ; be used in assembly routines. This evaluates to nothing in the flat memory
438 ; model, but is saves and restores DS in the large memory model.
464 ; Macros for loading the address of a data pointer into a segment and
465 ; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
466 ; memory model, or it simply loads the offset into the register in the flat
467 ; memory model since DS and ES always point to all addressable memory. You
468 ; must use the correct _REG (ie: _BX) %imacros for documentation purposes.
486 ; Macros for adding and subtracting a value from registers. Two value are
487 ; provided, one for 16 bit modes and another for 32 bit modes (the extended
488 ; register is used in 32 bit modes).
506 ; Macro to clear the high order word for the 32 bit extended registers.
507 ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
508 ; value, and will evaluate to nothing in 16 bit modes.
522 ; Macro to load an extended register with an integer value in either mode
533 ; Macros to load and store integer values with string instructions
551 ; Macros to provide resb, resw, resd compatibility with NASM
565 ; Macro to get the addres of the GOT for Linux/FreeBSD shared
566 ; libraries into the EBX register.
571 add %1,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc
574 ; Macro to get the address of a *local* variable that is global to
575 ; a single module in a manner that will work correctly when compiled
576 ; into a Linux shared library. Note that this will *not* work for
577 ; variables that are defined as global to all modules. For that
578 ; use the LEA_G macro
583 lea %1,[%1+%2 wrt ..gotoff]
589 ; Same macro as above but for global variables public to *all*
595 mov %1,[%1+%2 wrt ..got]
601 ; macros to declare assembler function stubs for function structures
603 %imacro BEGIN_STUBS_DEF 2
607 %define STUBS_START %1
610 %define STUBS_START _%1
617 %imacro DECLARE_STUB 1
622 mov eax,[eax+STUBS_START wrt ..got]
632 jmp [DWORD STUBS_START+off]
641 %imacro DECLARE_STDCALL 2
642 %ifdef STDCALL_MANGLE
646 %ifdef STDCALL_USCORE
654 jmp [DWORD STUBS_START+off]
658 %imacro END_STUBS_DEF 0
662 ; macros to declare assembler import stubs for binary loadable drivers
664 %imacro BEGIN_IMPORTS_DEF 1
668 %imacro DECLARE_IMP 2
684 %imacro END_IMPORTS_DEF 0
688 else ; __NASM_MAJOR__
690 ;============================================================================
691 ; Macro package when compiling with TASM.
692 ;============================================================================
694 ; Turn off underscores for globals if disabled for all externals
700 ; Define the __WINDOWS__ symbol if we are compiling for any Windows
708 __WINDOWS32_386__ = 1
712 __WINDOWS32_386__ = 1
716 __WINDOWS32_386__ = 1
720 include vmm.inc ; IGNORE DEPEND
721 include vsegment.inc ; IGNORE DEPEND
725 ; Macros for accessing 'generic' registers
728 _ax EQU eax ; EAX is used for accumulator
729 _bx EQU ebx ; EBX is used for accumulator
730 _cx EQU ecx ; ECX is used for looping
731 _dx EQU edx ; EDX is used for data register
732 _si EQU esi ; ESI is the source index register
733 _di EQU edi ; EDI is the destination index register
734 _bp EQU ebp ; EBP is used for base pointer register
735 _sp EQU esp ; ESP is used for stack pointer register
736 _es EQU ; ES and DS are the same in 32 bit PM
737 typedef UCHAR BYTE ; Size of a character
738 typedef USHORT WORD ; Size of a short
739 typedef UINT DWORD ; Size of an integer
740 typedef ULONG DWORD ; Size of a long
741 typedef BOOL DWORD ; Size of a boolean
742 typedef DPTR DWORD ; Size of a data pointer
743 typedef FDPTR FWORD ; Size of a far data pointer
744 typedef NDPTR DWORD ; Size of a near data pointer
745 typedef CPTR DWORD ; Size of a code pointer
746 typedef FCPTR FWORD ; Size of a far code pointer
747 typedef NCPTR DWORD ; Size of a near code pointer
748 typedef DUINT DWORD ; Declare a integer variable
749 FPTR EQU NEAR ; Distance for function pointers
750 intsize = 4 ; Size of an integer
751 flatmodel = 1 ; This is a flat memory model
752 P386 ; Turn on 386 code generation
753 MODEL FLAT ; Set up for 32 bit simplified FLAT model
755 _ax EQU ax ; AX is used for accumulator
756 _bx EQU bx ; BX is used for accumulator
757 _cx EQU cx ; CX is used for looping
758 _dx EQU dx ; DX is used for data register
759 _si EQU si ; SI is the source index register
760 _di EQU di ; DI is the destination index register
761 _bp EQU bp ; BP is used for base pointer register
762 _sp EQU sp ; SP is used for stack pointer register
763 _es EQU es: ; ES is used for segment override
764 typedef UCHAR BYTE ; Size of a character
765 typedef USHORT WORD ; Size of a short
766 typedef UINT WORD ; Size of an integer
767 typedef ULONG DWORD ; Size of a long
768 typedef BOOL WORD ; Size of a boolean
769 typedef DPTR DWORD ; Size of a data pointer
770 typedef FDPTR DWORD ; Size of a far data pointer
771 typedef NDPTR WORD ; Size of a near data pointer
772 typedef CPTR DWORD ; Size of a code pointer
773 typedef FCPTR DWORD ; Size of a far code pointer
774 typedef NCPTR WORD ; Size of a near code pointer
775 typedef DUINT WORD ; Declare a integer variable
776 FPTR EQU FAR ; Distance for function pointers
777 intsize = 2 ; Size of an integer
778 P386 ; Turn on 386 code generation
782 ; Provide a typedef for real floating point numbers
792 ; Macros to access the floating point stack registers to convert them
793 ; from NASM style to TASM style
805 ; Boolean truth values (same as those in debug.h)
815 ; Macros for the _DATA data segment. This segment contains initialised data.
817 MACRO begdataseg name
826 SEGMENT _DATA DWORD PUBLIC USE16 'DATA'
831 MACRO enddataseg name
843 ; Macro for the main code segment.
845 MACRO begcodeseg name
853 ASSUME CS:FLAT,DS:FLAT,SS:FLAT
855 SEGMENT &name&_TEXT PARA PUBLIC USE16 'CODE'
856 ASSUME CS:&name&_TEXT,DS:_DATA
861 ; Macro for a near code segment
863 MACRO begcodeseg_near
866 ASSUME CS:FLAT,DS:FLAT,SS:FLAT
868 SEGMENT _TEXT PARA PUBLIC USE16 'CODE'
869 ASSUME CS:_TEXT,DS:_DATA
873 MACRO endcodeseg name
885 MACRO endcodeseg_near
891 ; Macro to be invoked at the start of all modules to set up segments for
899 ; Macro for an extern C symbol. If the C compiler requires leading
900 ; underscores, then the underscores are added to the symbol names, otherwise
901 ; they are left off. The symbol name is referenced in the assembler code
902 ; using the non-underscored symbol name.
904 MACRO cextern name,size
913 MACRO cexternfunc name,size
922 MACRO stdexternfunc name,num_args,size
924 EXTRN _&name&@&num_args&:size
925 name EQU _&name&@&num_args
931 ; Macro for a public C symbol. If the C compiler requires leading
932 ; underscores, then the underscores are added to the symbol names, otherwise
933 ; they are left off. The symbol name is referenced in the assembler code
934 ; using the non-underscored symbol name.
947 ; Macro for an global C symbol. If the C compiler requires leading
948 ; underscores, then the underscores are added to the symbol names, otherwise
949 ; they are left off. The symbol name is referenced in the assembler code
950 ; using the non-underscored symbol name.
961 ; Macro for an global C function symbol. If the C compiler requires leading
962 ; underscores, then the underscores are added to the symbol names, otherwise
963 ; they are left off. The symbol name is referenced in the assembler code
964 ; using the non-underscored symbol name.
966 MACRO cglobalfunc name
975 ; Macro to start a C callable function. This will be a far function for
976 ; 16-bit code, and a near function for 32-bit code.
978 MACRO cprocstatic name ; Set up model independant private proc
987 MACRO cprocstart name ; Set up model independant proc
1005 MACRO cprocnear name ; Set up near proc
1015 MACRO cprocfar name ; Set up far proc
1025 MACRO cprocend ; End procedure macro
1029 ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
1030 ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
1031 ; rename this routine with an extra underscore with 'C' calling conventions
1032 ; and a small DLL stub will be provided by the high level code to call the
1033 ; assembler routine.
1035 MACRO cprocstartdll16 name
1043 ; Macros for entering and exiting C callable functions. Note that we must
1044 ; always save and restore the SI and DI registers for C functions, and for
1045 ; 32 bit C functions we also need to save and restore EBX and clear the
1059 IFDIFI <LocalSize>,<0>
1065 MACRO restore_c_regs
1076 IFDIFI <LocalSize>,<0>
1094 ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
1095 ; be used in assembly routines. This evaluates to nothing in the flat memory
1096 ; model, but is saves and restores DS in the large memory model.
1122 ; Macros for loading the address of a data pointer into a segment and
1123 ; index register pair. The macro explicitly loads DS or ES in the 16 bit
1124 ; memory model, or it simply loads the offset into the register in the flat
1125 ; memory model since DS and ES always point to all addressable memory. You
1126 ; must use the correct _REG (ie: _BX) macros for documentation purposes.
1128 MACRO _lds reg, addr
1136 MACRO _les reg, addr
1144 ; Macros for adding and subtracting a value from registers. Two value are
1145 ; provided, one for 16 bit modes and another for 32 bit modes (the extended
1146 ; register is used in 32 bit modes).
1148 MACRO _add reg, val16, val32
1156 MACRO _sub reg, val16, val32
1164 ; Macro to clear the high order word for the 32 bit extended registers.
1165 ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
1166 ; value, and will evaluate to nothing in 16 bit modes.
1180 ; Macro to load an extended register with an integer value in either mode
1182 MACRO loadint reg,val
1191 ; Macros to load and store integer values with string instructions
1209 ; Macros to provide resb, resw, resd compatibility with NASM
1223 ; Macros to provide resb, resw, resd compatibility with NASM
1237 ; Macros to declare assembler stubs for function structures
1239 MACRO BEGIN_STUBS_DEF name, firstOffset
1247 STUBS_START = _&name
1254 MACRO DECLARE_STUB name
1262 jmp [DWORD STUBS_START+off]
1266 MACRO SKIP_STUB name
1270 MACRO DECLARE_STDCALL name,num_args
1271 ifdef STDCALL_MANGLE
1273 PUBLIC _&name&@&num_args&
1278 jmp [DWORD STUBS_START+off]
1286 MACRO BEGIN_IMPORTS_DEF name
1287 BEGIN_STUBS_DEF name,4
1290 ifndef LOCAL_DECLARE_IMP
1291 MACRO DECLARE_IMP name, numArgs
1299 MACRO SKIP_IMP2 name, numArgs
1303 MACRO SKIP_IMP3 name
1308 MACRO END_IMPORTS_DEF
1312 MACRO LEA_L reg,name
1316 MACRO LEA_G reg,name