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

📄 cruntime.inc

📁 C标准库源代码
💻 INC
📖 第 1 页 / 共 2 页
字号:
;***
;cruntime.inc - multi-model assembly macros for interfacing to HLLs
;
;       Copyright (c) 1988-1997, Microsoft Corporation.  All rights reserved.
;
;Purpose:
;       This file defines the current memory model being used.
;
;*******************************************************************************

;==============================================================================
;
;Use the following defines to control processor/segment model
;
;   -DI86               8086/8088 processor
;   -DI286              80286 processor
;   -DI386              80386 processor with 32-bit code/data segment
;
;   -Dmem_S             Small memory model   (near code, near data)
;   -Dmem_M             Medium memory model  (far code, near data)
;   -Dmem_C             Compact memory model (near code, fat data)
;   -Dmem_L             Large memory model   (far code, far data)
;
;   -DSS_NEQ_DGROUP     SS and DS point to different segments
;
;   default is -DI86 -Dmem_S
;
;==============================================================================
;
;The following variables are defined by this file:
;   cpu                         86, 286, or 386
;   sizeC                       code distance; 1 = far code, 0 = near code
;   sizeD                       data distance; 1 = far data, 0 = near data
;   mmodel                      english name of the memory model, i.e. "Medium"
;   ISIZE, LSIZE, NSIZE         size of ints, longs, shorts
;   FLTSIZE, DBLSIZE, LDBLSIZE  size of float, double, long double
;   NPSIZE, FPSIZE              size of near/far pointers
;   CPSIZE, DPSIZE              size of code/data pointers
;   ISHIFT, LSHIFT              bits to shift to convert byte to int/long
;
;The following macros allow easy writing of combined 16/32 bit code:
;
; 16/32 bit registers:
;   rax, rbx, rcx, rdx,         expand to native registers (rax = eax or ax)
;   rsi, rdi, rsp, rbp
; 16/32 bit register instructions:
;   JRCXZ                       jump when rcx is zero
;   CBI                         convert byte to int (al to rax)
;   CAXDX                       convert rax to rax:rdx
;   ZXAL, ZXBL, ZXCL, ZXDL      zero extend al,bl,cl,dl to rax,rbx,rcx,rdx
; Pointer instructions:
;   LPDS, LPES                  load data pointer with ES or DS
;   PDS, PES                    segment overrides when pointer loaded as above
;   PCS, PSS                    segment override to get at code/stack segment
;   LFPDS, LFPES                load far pointer with ES or DS
;   FPDS, FPES                  segment overrides when pointer loaded as above
;   CPTR                        data type of code pointer
;   CPDIST                      distance of code (near/far)
;   DNPTR, DFPTR                define near/far pointer
;   DCPTR, DDPTR                define code/data pointer
;   DCPTR?, DDPTR?              define uninitialized code/data pointer
;   CPWORD, DPWORD              data type of code or data pointer
; Numeric type instructions:
;   IWORD, LWORD, SWORD         data type of int, long, short
;   DINT, DLONG, DSHORT         define int, long, short
;   DFLOAT, DDOUBLE, DLDOUBLE   define float, double, long double
; Offsets:
;   codeoffset, dataoffset      offsets from code and data segments
; API calls:
;   APIDIST                     distance of API calls (near/far)
;   APIEXT ApiName              extrn declaration for an API function
;
;The following utility macros are provided:
;   codeseg                     define/declare code segment
;   error <msg>                 stop assembly with message
;   display <msg>               display a message, unless QUIET defined
;   savelist [<reg> ...]        init list of regs to be save by 'proc uses'
;   _if cond <instruction>      assemble instruction only if cond is TRUE
;   _ife cond <instruction>     assemble instruction only if cond is FALSE
;   _ifd symbol <instruction>   assemble instruction only if symbol defined
;   _ifnd symbol <instruction>  assemble instruction only if symbol not defined
;
;   lab  LabelName              assembles to "LabelName:" If DEBUG is defined
;                               LabelName is made public
;
;   JS* (ex. JSE,JSZ,JSB ...)   assemble to "je short","jz short","jb short"
;
;   Cmacro look alikes
;   static* Name, InitialValue, Repeat   defines a static variable of type *
;   global* Name, InitialValue, Repeat   defines a global variable of type *
;   label*  Name, {PUBLIC,PASCAL,C}      defines a label of type *
;
;   PUSH16  SegmentReg          pushes 16 bits in a use32 segment
;   JMPFAR16  label             will do a far 16:16 jmp from a use32 segment
;
;==============================================================================

; error <msg>   -    Output message and generate error

error   MACRO   msg
if2                     ;; only on pass 2 can we generate errors
        %out    **********************************************************
        %out    *** E r r o r  --  msg
        %out    **********************************************************
        .err
endif
        ENDM

; display msg   -    Output message unless QUIET defined

display MACRO   msg
ifndef QUIET            ;; only when quiet flag not set
if1                     ;; and on pass 1, then display message
        %out msg
endif
endif
        ENDM

; One line conditionals:
;   here we create the capability of writing code lines like
;
; _if sizeD   <push ds>   as opposed to    if sizeD
;                                              push  ds
;                                          endif

_if     MACRO   cond,text
    if  cond
        text
    endif
        ENDM

_ife    MACRO   cond,text
    ife cond
        text
    endif
        ENDM

_ifd    MACRO   cond,text
    ifdef   cond
        text
    endif
        ENDM

_ifnd   MACRO   cond,text
    ifndef  cond
        text
    endif
        ENDM

; set windows flag to 0

        ?WIN    equ     0       ; disable windows-specific code

; check for _MT, requires 286 or greater processor

ifdef _MT
ifndef I386
ifndef I286
; _MT implies 286 processor
display <Multi-thread specified - assuming 80286 processor>
I286 equ <>
endif
endif
endif

; Process memory-model arguments

ifdef  mem_M
        ; Medium model
        sizeC   equ     1
        sizeD   equ     0
        mmodel  equ     <Medium>
elseifdef  mem_C
        ; Compact model
        sizeC   equ     0
        sizeD   equ     1
        mmodel  equ     <Compact>
elseifdef  mem_L
        ; Large model
        sizeC   equ     1
        sizeD   equ     1
        mmodel  equ     <Large>
else
        ; Small model - default
        sizeC   equ     0
        sizeD   equ     0
        mmodel  equ     <Small>
endif

; Process processor arguments

ifdef   _WIN32
        display <Processor:             486/586>
        cpu equ 586
        .586
elseifdef       _POSIX_
        display <Processor:             486/586>
        cpu equ 586
        .586
elseifdef   I286
        display <Processor:             80286>
        cpu equ 286
        .286
elseifdef   I386
        display <Processor:             80386>
        cpu equ 386
        .386
else
        display <Processor:             8086/8088>
        cpu equ 86
        .8086
endif

;  386 32-bit checking.  Currently we are only expecting small model
;  32 bit segments, so we make a few checks to be sure nothing is
;  incorrectly being defined.

ifdef I386
    if sizeC or sizeD
        error <Must use Small memory model for 386 version.>
    endif

    ifdef _LOAD_DGROUP
        error <No loading DGROUP in 386 version.>
    endif

    ifdef SS_NEQ_DGROUP
        error <SS always equals DGROUP in 386 version.>
    endif
endif

;  Set memory model

%       display <Memory model:          mmodel>
%       .model  mmodel, C

;
; *** Temporary Workaround ***
; Currently, MASM will not recognize the 'FLAT' keyword unless it previously
; appears in an 'assume' statement.  Presumably, when the '.model FLAT' feature
; is implemented, this will go away.  [Use 'gs:' since we never use that
; segment register.
;

ifdef   I386
        ; ensure that MASM recognizes 'FLAT'
        assume  gs:FLAT
endif


; Define registers:
; Instead of using the "word" registers directly, we will use a set of
; text equates.  This will allow you to use the native word size instead of
; hard coded to 16 bit words.  We also have some instruction equates for
; instruction with the register type hard coded in.

ifdef I386

    rax equ <eax>
    rbx equ <ebx>
    rcx equ <ecx>
    rdx equ <edx>
    rdi equ <edi>
    rsi equ <esi>
    rbp equ <ebp>
    rsp equ <esp>

    JRCXZ equ <jecxz>
    CBI   equ <movsx eax, al>    ; convert byte to int (al to rax)
    CAXDX equ <cdq>              ; convert rax to rdx:rax
    ZXAL  equ <movzx eax, al>    ; zero extend al
    ZXBL  equ <movzx ebx, bl>    ; zero extend bl
    ZXCL  equ <movzx ecx, cl>    ; zero extend cl
    ZXDL  equ <movzx edx, dl>    ; zero extend dl

else

    rax equ <ax>
    rbx equ <bx>
    rcx equ <cx>
    rdx equ <dx>
    rdi equ <di>
    rsi equ <si>
    rbp equ <bp>
    rsp equ <sp>

    JRCXZ equ <jcxz>
    CBI   equ <cbw>              ; convert byte to int (al to rax)
    CAXDX equ <cwd>              ; convert rax to rdx:rax
    ZXAL  equ <xor ah, ah>       ; zero extend al
    ZXBL  equ <xor bh, bh>       ; zero extend bl
    ZXCL  equ <xor ch, ch>       ; zero extend cl
    ZXDL  equ <xor dh, dh>       ; zero extend dl

endif

; The following equates deal with the differences in near versus
; far data pointers, and segment overrides.
;
; Use LPES and PES when loading a default size pointer -- it loads
; a 16-bit pointer register in 286 Small/Medium model,
; a 16-bit pointer register and 16-bit segment register in 8086/286
; Compact/Large model, and a 32-bit pointer register in 386 mode.
;
; Use LFPES and FPES when loading an always far pointer -- it loads a
; 16-bit pointer register and 16-bit segment register in 8086/286,
; all models; a 32-bit pointer register in 386 mode.

if sizeD
    LPES equ <les>
    LPDS equ <lds>
    PDS  equ <ds:>
    PES  equ <es:>
else
    LPES equ <mov>
    LPDS equ <mov>
    PDS  equ <>
    PES  equ <>
endif

ifdef I386
    LFPES equ <mov>
    LFPDS equ <mov>
    FPES equ <>
    FPDS equ <>
else
    LFPES equ <les>
    LFPDS equ <lds>
    FPES equ <es:>
    FPDS equ <ds:>
endif

if sizeC or @WordSize eq 2
    PCS  equ <cs:>              ; large code model or non-386
else
 IF 1   ;*** TEMP 16/32 TESTBED ***
    PCS  equ <cs:>
 ELSE
    PCS  equ <>                 ; 386 small code model
 ENDIF  ;*** END TEMP CODE
endif

ifdef SS_NEQ_DGROUP
    PSS   equ <ss:>             ; SS != DS
else
    PSS   equ <>                ; SS == DS
endif

; Define offset macros:
;   The 32-bit segments will not have 'groups'

ifdef I386
    codeoffset  equ <offset FLAT:>
    dataoffset  equ <offset FLAT:>
else
    codeoffset  equ <offset @code:>
    dataoffset  equ <offset DGROUP:>
endif

; The next set of equates deals with the size of SHORTS, INTS, LONGS, and
; pointers in the 16 and 32 bit versions.

ifdef I386       ;--- 32 bit segment ---

    ; parameters and locals
    IWORD   equ <dword>
    LWORD   equ <dword>

    ; static storage
    DINT    equ <dd>
    DLONG   equ <dd>
    DSHORT  equ <dw>

    ; sizes for fixing SP, stepping through tables, etc.
    ISIZE   equ 4
    LSIZE   equ 4
    SSIZE   equ 2
    NPSIZE  equ 4
    FPSIZE  equ 4

    ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr
    ISHIFT  equ 2               ; byte-to-int shift count
    LSHIFT  equ 2               ; byte-to-long shift count

    ; sizes dependent upon memory model.  dq -vs- df is not yet clear
    DNPTR equ <dd>              ; near pointer
    DFPTR equ <dd>              ; far pointer

    DCPTR   equ <dd offset FLAT:>; 32 bit offset only
    DCPTR?  equ <dd>            ; No seg override for uninitialized values
    CPSIZE  equ 4
    CPDIST  equ <near>          ; code pointers are near

⌨️ 快捷键说明

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