⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scitech.mac

📁 一个免费的汇编语言编译器的源代码
💻 MAC
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************
;*
;*  ========================================================================
;*
;*    The contents of this file are subject to the SciTech MGL Public
;*    License Version 1.0 (the "License"); you may not use this file
;*    except in compliance with the License. You may obtain a copy of
;*    the License at http://www.scitechsoft.com/mgl-license.txt
;*
;*    Software distributed under the License is distributed on an
;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
;*    implied. See the License for the specific language governing
;*    rights and limitations under the License.
;*
;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
;*
;*    The Initial Developer of the Original Code is SciTech Software, Inc.
;*    All Rights Reserved.
;*
;*  ========================================================================
;*
;* Language:    NetWide Assembler (NASM) or Turbo Assembler (TASM)
;* Environment: Any Intel Environment
;*
;* Description: Macros to provide memory model independant assembly language
;*              module for C programming. Supports the large and flat memory
;*				models.
;*
;*          	The defines that you should use when assembling modules that
;*				use this macro package are:
;*
;*					__LARGE__	Assemble for 16-bit large model
;*                  __FLAT__    Assemble for 32-bit FLAT memory model
;*                  __NOU__		No underscore for all external C labels
;*					__NOU_VAR__	No underscore for global variables only
;*
;*				The default settings are for 16-bit large memory model with
;*				leading underscores for symbol names.
;*
;*				The main intent of the macro file is to enable programmers
;*				to write _one_ set of source that can be assembled to run
;*				in either 16 bit real and protected modes or 32 bit
;*				protected mode without the need to riddle the code with
;*				'if flatmodel' style conditional assembly (it is still there
;*				but nicely hidden by a macro layer that enhances the
;*				readability and understandability of the resulting code).
;*
;****************************************************************************

; Include the appropriate version in here depending on the assembler. NASM
; appears to always try and parse code, even if it is in a non-compiling
; block of a ifdef expression, and hence crashes if we include the TASM
; macro package in the same header file. Hence we split the macros up into
; two separate header files.

ifdef __NASM_MAJOR__

;============================================================================
; Macro package when compiling with NASM.
;============================================================================

; Turn off underscores for globals if disabled for all externals

%ifdef	__NOU__
%define	__NOU_VAR__
%endif

; Define the __WINDOWS__ symbol if we are compiling for any Windows
; environment

%ifdef	__WINDOWS16__
%define	__WINDOWS__			1
%endif
%ifdef	__WINDOWS32__
%define __WINDOWS__			1
%define __WINDOWS32_386__	1
%endif

; Macros for accessing 'generic' registers

%ifdef	__FLAT__
%idefine _ax	eax
%idefine _bx	ebx
%idefine _cx	ecx
%idefine _dx	edx
%idefine _si	esi
%idefine _di	edi
%idefine _bp	ebp
%idefine _sp	esp
%idefine _es
%idefine UCHAR 	BYTE		; Size of a character
%idefine USHORT WORD		; Size of a short
%idefine UINT 	DWORD		; Size of an integer
%idefine ULONG 	DWORD		; Size of a long
%idefine BOOL 	DWORD      	; Size of a boolean
%idefine DPTR 	DWORD		; Size of a data pointer
%idefine FDPTR 	FWORD		; Size of a far data pointer
%idefine NDPTR 	DWORD		; Size of a near data pointer
%idefine CPTR 	DWORD		; Size of a code pointer
%idefine FCPTR 	FWORD		; Size of a far code pointer
%idefine NCPTR 	DWORD		; Size of a near code pointer
%idefine FPTR 	NEAR		; Distance for function pointers
%idefine DUINT	dd			; Declare a integer variable
%idefine intsize 4
%idefine flatmodel 1
%else
%idefine _ax	ax
%idefine _bx	bx
%idefine _cx	cx
%idefine _dx	dx
%idefine _si	si
%idefine _di	di
%idefine _bp	bp
%idefine _sp	sp
%idefine _es	es:
%idefine UCHAR 	BYTE      	; Size of a character
%idefine USHORT WORD		; Size of a short
%idefine UINT 	WORD		; Size of an integer
%idefine ULONG 	DWORD		; Size of a long
%idefine BOOL 	WORD		; Size of a boolean
%idefine DPTR 	DWORD		; Size of a data pointer
%idefine FDPTR 	DWORD		; Size of a far data pointer
%idefine NDPTR 	WORD		; Size of a near data pointer
%idefine CPTR 	DWORD		; Size of a code pointer
%idefine FCPTR 	DWORD		; Size of a far code pointer
%idefine NCPTR 	WORD		; Size of a near code pointer
%idefine FPTR   FAR			; Distance for function pointers
%idefine DUINT	dw			; Declare a integer variable
%idefine intsize 2
%endif
%idefine invert ~
%idefine offset
%idefine use_nasm

; Convert all jumps to near jumps, since NASM does not so this automatically

%idefine jo		jo near
%idefine jno	jno near
%idefine jz		jz near
%idefine jnz	jnz near
%idefine je		je near
%idefine jne	jne near
%idefine jb		jb	near
%idefine jbe	jbe	near
%idefine ja		ja	near
%idefine jae	jae	near
%idefine jl		jl	near
%idefine jle	jle	near
%idefine jg		jg	near
%idefine jge	jge	near
%idefine jc		jc	near
%idefine jnc	jnc	near
%idefine js		js	near
%idefine jns	jns	near

%ifdef	DOUBLE
%idefine	REAL	QWORD
%idefine	DREAL	dq
%else
%idefine	REAL	DWORD
%idefine	DREAL	dd
%endif

; Boolean truth values (same as those in debug.h)

%idefine False		0
%idefine True		1
%idefine No			0
%idefine Yes		1
%idefine Yes		1

; Macro to be invoked at the start of all modules to set up segments for
; later use. Does nothing for NASM.

%imacro header 1
%endmacro

; Macro to begin a data segment

%imacro begdataseg 1
%ifdef __GNUC__
segment .data public class=DATA use32 flat
%else
%ifdef flatmodel
segment _DATA public align=4 class=DATA use32 flat
%else
segment _DATA public align=4 class=DATA use16
%endif
%endif
%endmacro

; Macro to end a data segment

%imacro enddataseg 1
%endmacro

; Macro to begin a code segment

%imacro begcodeseg 1
%ifdef __GNUC__
segment .text public class=CODE use32 flat
%else
%ifdef flatmodel
segment _TEXT public align=16 class=CODE use32 flat
%else
segment %1_TEXT public align=16 class=CODE use16
%endif
%endif
%endmacro

; Macro to begin a near code segment

%imacro begcodeseg_near 0
%ifdef __GNUC__
segment .text public class=CODE use32 flat
%else
%ifdef flatmodel
segment _TEXT public align=16 class=CODE use32 flat
%else
segment _TEXT public align=16 class=CODE use16
%endif
%endif
%endmacro

; Macro to end a code segment

%imacro endcodeseg 1
%endmacro

; Macro to end a near code segment

%imacro endcodeseg_near 0
%endmacro

; Macro for an extern C symbol. If the C compiler requires leading
; underscores, then the underscores are added to the symbol names, otherwise
; they are left off. The symbol name is referenced in the assembler code
; using the non-underscored symbol name.

%imacro cextern 2
%ifdef	__NOU_VAR__
extern %1
%else
extern _%1
%define	%1 _%1
%endif
%endmacro

%imacro cexternfunc 2
%ifdef	__NOU__
extern %1
%else
extern _%1
%define	%1 _%1
%endif
%endmacro

; Macro for a public C symbol. If the C compiler requires leading
; underscores, then the underscores are added to the symbol names, otherwise
; they are left off. The symbol name is referenced in the assembler code
; using the non-underscored symbol name.

%imacro cpublic 1
%ifdef	__NOU_VAR__
global %1
%1:
%else
global _%1
_%1:
%define	%1 _%1
%endif
%endmacro

; Macro for an global C symbol. If the C compiler requires leading
; underscores, then the underscores are added to the symbol names, otherwise
; they are left off. The symbol name is referenced in the assembler code
; using the non-underscored symbol name.

%imacro cglobal 1
%ifdef	__NOU_VAR__
global %1
%else
global _%1
%define	%1 _%1
%endif
%endmacro

; Macro for an global C function symbol. If the C compiler requires leading
; underscores, then the underscores are added to the symbol names, otherwise
; they are left off. The symbol name is referenced in the assembler code
; using the non-underscored symbol name.

%imacro cglobalfunc 1
%ifdef	__NOU__
global %1
%else
global _%1
%define	%1 _%1
%endif
%endmacro

; Macro to start a C callable function. This will be a far function for
; 16-bit code, and a near function for 32-bit code.

%imacro cprocstatic 1
%push cproc
%1:
%ifdef flatmodel
%stacksize flat
%define ret	retn
%else
%stacksize large
%define ret	retf
%endif
%assign %$localsize 0
%endmacro

%imacro cprocstart 1
%push cproc
	cglobalfunc %1
%1:
%ifdef flatmodel
%stacksize flat
%define ret	retn
%else
%stacksize large
%define ret	retf
%endif
%assign %$localsize 0
%endmacro

; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
; calling conventions are always _far _pascal for 16 bit DLL's, we actually
; rename this routine with an extra underscore with 'C' calling conventions
; and a small DLL stub will be provided by the high level code to call the
; assembler routine.

%imacro	cprocstartdll16 1
%ifdef	__WINDOWS16__
cprocstart	_%1
%else
cprocstart	%1
%endif
%endmacro

; Macro to start a C callable near function.

%imacro cprocnear 1
%push cproc
	cglobalfunc %1
%1:
%define ret	retn
%ifdef flatmodel
%stacksize flat
%else
%stacksize small
%endif
%assign %$localsize 0
%endmacro

; Macro to start a C callable far function.

%imacro cprocfar 1
%push cproc
	cglobalfunc %1
%1:
%define ret	retf
%ifdef flatmodel
%stacksize flat
%else
%stacksize large
%endif
%assign %$localsize 0
%endmacro

; Macro to end a C function

%imacro cprocend 0
%pop
%endmacro

; Macros for entering and exiting C callable functions. Note that we must
; always save and restore the SI and DI registers for C functions, and for
; 32 bit C functions we also need to save and restore EBX and clear the
; direction flag.

%imacro enter_c 0
		push    _bp
		mov     _bp,_sp
%ifnidn	%$localsize,0
		sub		_sp,%$localsize
%endif
%ifdef	flatmodel
		push	ebx
%endif
		push	_si
		push	_di
%endmacro

%imacro leave_c 0
		pop		_di
		pop		_si
%ifdef	flatmodel
		pop		ebx
		cld
%endif
%ifnidn %$localsize,0
		mov     _sp,_bp
%endif
		pop     _bp
%endmacro

%imacro   use_ebx 0
%ifdef flatmodel
		push    ebx
%endif
%endmacro

%imacro   unuse_ebx 0
%ifdef flatmodel
		pop     ebx
%endif
%endmacro

; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
; be used in assembly routines. This evaluates to nothing in the flat memory
; model, but is saves and restores DS in the large memory model.

%imacro	use_ds 0
%ifndef flatmodel
		push	ds
%endif
%endmacro

%imacro	unuse_ds 0
%ifndef flatmodel
		pop		ds
%endif
%endmacro

%imacro	use_es 0
%ifndef flatmodel
		push	es
%endif
%endmacro

%imacro	unuse_es 0
%ifndef flatmodel
		pop		es
%endif
%endmacro

; Macros for loading the address of a data pointer into a segment and
; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
; memory model, or it simply loads the offset into the register in the flat
; memory model since DS and ES always point to all addressable memory. You
; must use the correct _REG (ie: _BX) %imacros for documentation purposes.

%imacro	_lds	2
%ifdef flatmodel
		mov     %1,%2
%else
		lds		%1,%2
%endif
%endmacro

%imacro   _les	2
%ifdef flatmodel
		mov     %1,%2
%else
		les		%1,%2
%endif
%endmacro

; Macros for adding and subtracting a value from registers. Two value are
; provided, one for 16 bit modes and another for 32 bit modes (the extended
; register is used in 32 bit modes).

%imacro   _add	3
%ifdef flatmodel
		add		e%1, %3
%else
		add		%1, %2
%endif
%endmacro

%imacro	_sub	3
%ifdef flatmodel
		sub		e%1, %3
%else
		sub		%1, %2
%endif
%endmacro

; Macro to clear the high order word for the 32 bit extended registers.
; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
; value, and will evaluate to nothing in 16 bit modes.

%imacro	clrhi	1
%ifdef	flatmodel
		movzx	e%1,%1
%endif
%endmacro

%imacro	sgnhi	1
%ifdef	flatmodel
		movsx	e%1,%1
%endif
%endmacro

; Macro to load an extended register with an integer value in either mode

%imacro	loadint	2
%ifdef flatmodel
		mov		e%1,%2
%else
		xor		e%1,e%1
		mov     %1,%2
%endif
%endmacro

; Macros to load and store integer values with string instructions

%imacro	LODSINT 0
%ifdef flatmodel
		lodsd
%else
		lodsw
%endif
%endmacro

%imacro	STOSINT	0
%ifdef flatmodel
		stosd
%else
		stosw
%endif
%endmacro

; Macros to provide resb, resw, resd compatibility with NASM

%imacro	dclb 1
times %1 db 0
%endmacro

%imacro	dclw 1
times %1 dw 0
%endmacro

%imacro	dcld 1
times %1 dd 0
%endmacro

; macros to declare assembler function stubs for function structures

%imacro	BEGIN_STUBS_DEF	2
begdataseg  _STUBS
%ifdef	__NOU_VAR__
extern %1
%define	STUBS_START	%1
%else
extern _%1
%define	STUBS_START	_%1
%endif
enddataseg  _STUBS
begcodeseg  _STUBS
%assign off %2
%endmacro

%imacro   DECLARE_STUB	1
%ifdef	__NOU__
		global %1
%1:
%else
		global _%1
_%1:
%endif
		jmp     [DWORD STUBS_START+off]
%assign off off+4
%endmacro

%imacro DECLARE_STDCALL 2
%ifdef	STDCALL_MANGLE
		global _%1@%2
_%1@%2:
%else
%ifdef __GNUC__
		global _%1
_%1:
%else
		global %1
%1:
%endif
%endif
		jmp     [DWORD STUBS_START+off]
%assign off off+4
%endmacro

%imacro   END_STUBS_DEF 0
endcodeseg  _STUBS
%endmacro

; macros to declare assembler import stubs for binary loadable drivers

%imacro	BEGIN_IMPORTS_DEF	1
BEGIN_STUBS_DEF	%1,4
%endmacro

%imacro   DECLARE_IMP	1
DECLARE_STUB	%1
%endmacro

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -