codei86.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 1,210 行 · 第 1/3 页

ASM
1,210
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;*               DESCRIBE IT HERE!
;*
;*****************************************************************************

.8086

; CODEi86:     Pragma code bursts for built-in compiler pragmas
;
; - these routines are easier to code in assembler than in C

include struct.inc

beginb  macro   name
_&name&_name:
        db      "&name&",0
public  _&name
_&name:
        db      E_&name - _&name - 1
endm

endb    macro   name
E_&name:
endm

defsb    macro   name
_&name&_defs:
endm

        name    codei86

.286p

_DATA   segment word public 'DATA'
        assume  CS:_DATA

module_start:
        dw      _Functions - module_start

strcat_body     macro
        mov     cx,-1                   ; set length to -1
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     di                      ; point to null character
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          mov   [di],al                 ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          _quif e                       ; - ...
          mov   al,1[si]                ; - get next char
          add   si,2                    ; - bump up pointer
          mov   1[di],al                ; - copy it
          add   di,2                    ; - bump up pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        endm

BD_strcat_body  macro
        mov     cx,-1                   ; set length to -1
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     di                      ; point to null character
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          stosb                         ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          _quif e                       ; - ...
          mov   al,1[si]                ; - get next char
          add   si,2                    ; - bump up pointer
          stosb                         ; - copy it
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        endm

defsb   C_strcat
        db      "/* di strcat( di, si ) zaps ax,es,cx,si */",0
        db      "/* di strcat( di, si ) zaps ax,es,cx,si */",0
        db      "#define C_strcat_ret   HW_D( HW_DI )",0
        db      "#define C_strcat_parms P_DI_SI",0
        db      "#define C_strcat_saves HW_NotD_4( HW_AX, HW_ES, HW_CX, HW_SI )",0
        db      0

;       DI strcat( DI, SI )
;       ES,CX,AX and SI are modified
;
beginb  C_strcat
        push    ds                      ; set es=ds
        pop     es                      ; ...
        push    di                      ; save destination address
        strcat_body                     ; concatenate strings
        pop     di                      ; restore destination address
endb    C_strcat

defsb   S_strcat
        db      "/* di strcat( di, si ) zaps ax,es,si */",0
        db      "#define S_strcat_ret   HW_D( HW_DI )",0
        db      "#define S_strcat_parms P_DI_SI",0
        db      "#define S_strcat_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       DI strcat( DI, SI )
;       AX and SI are modified
;
beginb  S_strcat
        push    di                      ; save destination address
        dec     di                      ; back up one to start
        _loop                           ; loop (find end of first string)
          inc   di                      ; - point to next byte
          cmp   byte ptr [di],0         ; - check for null character
        _until  e                       ; until end of first string
        _loop                           ; loop (concatenate strings)
          lodsb                         ; - get char from src
          mov   [di],al                 ; - append to end of dest
          inc   di                      ; - point to next byte
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination string address
endb    S_strcat

defsb   ZF_strcat
        db      "/* es:di strcat( es:di, ds:si ) zaps ax,si */",0
        db      "#define ZF_strcat_ret    HW_D_2( HW_ES, HW_DI )",0
        db      "#define ZF_strcat_parms  P_ESDI_DSSI",0
        db      "#define ZF_strcat_saves  HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       ES:DI strcat( ES:DI, DS:SI )
;       AX and SI are modified
;
beginb  ZF_strcat
        push    di                      ; save destination address
        push    cx                      ; save cx
        mov     cx,-1                   ; set length to -1
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        pop     cx                      ; restore cx
        dec     di                      ; point to null character
        _loop                           ; loop (concatenate strings)
          lodsb                         ; - get char from src
          stosb                         ; - append to end of dest
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination string address
endb    ZF_strcat

defsb   ZP_strcat
        db      "/* es:di strcat( es:di, si:ax ) zaps ax,si */",0
        db      "#define ZP_strcat_ret    HW_D_2( HW_ES, HW_DI )",0
        db      "#define ZP_strcat_parms  P_ESDI_SIAX",0
        db      "#define ZP_strcat_saves  HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       ES:DI strcat( ES:DI, SI:AX )
;       AX and SI are modified
;
beginb  ZP_strcat
        push    ds                      ; save ds
        push    di                      ; save destination address
        xchg    si,ax                   ; get offset into si, segment into ax
        mov     ds,ax                   ; load segment
        push    cx                      ; save cx
        mov     cx,-1                   ; set length to -1
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        pop     cx                      ; restore cx
        dec     di                      ; point to null character
        _loop                           ; loop (concatenate strings)
          lodsb                         ; - get char from src
          stosb                         ; - append to end of dest
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination string address
        pop     ds                      ; restore ds
endb    ZP_strcat

defsb   DF_strcat
        db      "/* es:di strcat( es:di, ds:si ) zaps cx,ax,si */",0
        db      "#define DF_strcat_ret   HW_D_2( HW_ES, HW_DI )",0
        db      "#define DF_strcat_parms P_ESDI_DSSI",0
        db      "#define DF_strcat_saves HW_NotD_3( HW_CX, HW_AX, HW_SI )",0
        db      0
;
;       ES:DI strcat( ES:DI, DS:SI )
;       AX,CX and SI are modified
;
beginb  DF_strcat
        push    di                      ; save destination address
        BD_strcat_body
        pop     di                      ; restore destination address
endb    DF_strcat

defsb   DP_strcat
        db      "/* es:di strcat( es:di, si:ax ) zaps cx,ax,si */",0
        db      "#define DP_strcat_ret   HW_D_2( HW_ES, HW_DI )",0
        db      "#define DP_strcat_parms P_ESDI_SIAX",0
        db      "#define DP_strcat_saves HW_NotD_3( HW_CX, HW_AX, HW_SI )",0
        db      0
;
;       ES:DI _fstrcat( ES:DI, SI:AX )
;       AX,CX and SI are modified
;
beginb  DP_strcat
        push    ds                      ; save ds
        push    di                      ; save destination address
        xchg    si,ax                   ; get offset into si, segment into ax
        mov     ds,ax                   ; load segment
        BD_strcat_body
        pop     di                      ; restore destination string address
        pop     ds                      ; restore ds
endb    DP_strcat

;=======================================================================

defsb   C_strchr
        db      "/* si strchr( si, dl ) zaps ax,si */",0
        db      "#define C_strchr_ret   HW_D( HW_SI )",0
        db      "#define C_strchr_parms P_SI_DL",0
        db      "#define C_strchr_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       SI strchr( SI, DL )
;       AX and SI are modified
;
beginb  C_strchr
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          cmp   al,dl                   ; - quit if char found
          je    short E_C_strchr        ; - ...
          cmp   al,0                    ; - quit if end of string
          _quif e                       ; - ...
          inc   si                      ; - increment pointer
          mov   al,[si]                 ; - get next char
          cmp   al,dl                   ; - quit if char found
          je    short E_C_strchr        ; - ...
          inc   si                      ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        sub     si,si                   ; return NULL
endb    C_strchr

defsb   DF_strchr
        db      "/* dx:si strchr( ds:si, cl ) zaps ds,si,ax */",0
        db      "#define DF_strchr_ret  HW_D_2( HW_DX, HW_SI )",0
        db      "#define DF_strchr_parms P_DSSI_CL",0
        db      "#define DF_strchr_saves HW_NotD_3( HW_DX, HW_SI, HW_AX )",0
        db      0
;
;       DX:SI strchr( DS:SI, CL )
;       AX,DX and SI are modified
;
beginb  DF_strchr
        mov     dx,ds                   ; save ds
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          cmp   al,cl                   ; - quit if char found
          je    short E_DF_strchr       ; - ...
          inc   si                      ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        sub     si,si                   ; return NULL
        sub     dx,dx                   ; ...
endb    DF_strchr

defsb   DP_strchr
        db      "/* dx:si strchr( dx:si, cl ) zaps dx,si,ax */",0
        db      "#define DP_strchr_ret  HW_D_2( HW_DX, HW_SI )",0
        db      "#define DP_strchr_parms P_DXSI_CL",0
        db      "#define DP_strchr_saves HW_NotD_3( HW_DX, HW_SI, HW_AX )",0
        db      0
;
;       DX:SI strchr( DX:SI, CL )
;       AX,DX and SI are modified
;
beginb  DP_strchr
        push    ds                      ; save ds
        mov     ds,dx                   ; set ds
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          cmp   al,cl                   ; - quit if char found
          je    short _DP_strchr9       ; - ...
          inc   si                      ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        sub     si,si                   ; return NULL
        sub     dx,dx                   ; ...
_DP_strchr9:
        pop     ds                      ; restore ds
endb    DP_strchr

;=======================================================================

defsb   C_strcpy
        db      "/* di strcpy( di, si ) zaps ax,si */",0
        db      "#define C_strcpy_ret   HW_D( HW_DI )",0
        db      "#define C_strcpy_parms P_DI_SI",0
        db      "#define C_strcpy_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       DI strcpy( DI, SI )
;       AX and SI are modified
;
beginb  C_strcpy
        push    di                      ; save destination address
        _loop                           ; loop
          mov   al,[si]                 ; - get char from src
          mov   [di],al                 ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          _quif e                       ; - ...
          mov   al,1[si]                ; - get next char
          add   si,2                    ; - bump up pointer
          mov   1[di],al                ; - copy it
          add   di,2                    ; - bump up pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination address
endb    C_strcpy

defsb   S_strcpy
        db      "/* di strcpy( di, si ) zaps ax,si */",0
        db      "#define S_strcpy_ret   HW_D( HW_DI )",0
        db      "#define S_strcpy_parms P_DI_SI",0
        db      "#define S_strcpy_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       DI strcpy( DI, SI )
;       AX and SI are modified
;
beginb  S_strcpy
        push    di                      ; save destination address
        _loop                           ; loop
          lodsb                         ; - get char from src
          mov   [di],al                 ; - store in output buffer
          inc   di                      ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination address
endb    S_strcpy

defsb   ZF_strcpy
        db      "/* es:di strcpy( es:di, ds:si ) zaps ax,si */",0
        db      "#define ZF_strcpy_ret   HW_D_2( HW_ES, HW_DI )",0
        db      "#define ZF_strcpy_parms P_ESDI_DSSI",0
        db      "#define ZF_strcpy_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       ES:DI strcpy( ES:DI, DS:SI )
;       AX and SI are modified
;
beginb  ZF_strcpy
        push    di                      ; save destination address
        _loop                           ; loop
          lodsb                         ; - get char from src
          stosb                         ; - store in output buffer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     di                      ; restore destination address
endb    ZF_strcpy

defsb   ZP_strcpy
        db      "/* es:di strcpy( es:di, si:ax ) zaps ax,si */",0
        db      "#define ZP_strcpy_ret   HW_D_2( HW_ES, HW_DI )",0
        db      "#define ZP_strcpy_parms P_ESDI_SIAX",0
        db      "#define ZP_strcpy_saves HW_NotD_2( HW_AX, HW_SI )",0
        db      0
;
;       ES:DI strcpy( ES:DI, SI:AX )
;       AX and SI are modified
;
beginb  ZP_strcpy
        push    ds                      ; save ds
        push    di                      ; save destination address
        xchg    si,ax                   ; get offset into si, segment into ax
        mov     ds,ax                   ; load segment
        _loop                           ; loop
          lodsb                         ; - get char from src
          stosb                         ; - store in output buffer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string

⌨️ 快捷键说明

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