code386.asm

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

ASM
1,442
字号
;*****************************************************************************
;*
;*                            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!
;*
;*****************************************************************************


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

.386p

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    code386

_DATA   segment word public 'DATA'
        assume  CS:_DATA

module_start:
        dw      _Functions - module_start

defsb   C_strcat
        db      "/* edi strcat( edi, esi ) zaps eax,ecx,esi */",0
        db      "#define C_strcat_ret   HW_D( HW_EDI )",0
        db      "#define C_strcat_parms P_EDI_ESI",0
        db      "#define C_strcat_saves HW_NotD_3( HW_EAX, HW_ECX, HW_ESI )",0
        db      0
;
;       EDI strcat( EDI, ESI )
;       EAX,ECX and ESI are modified
;
beginb  C_strcat
        push    es                      ; save es
        push    ds                      ; set es=ds
        pop     es                      ; ...
        push    edi                     ; save destination address
        sub     ecx,ecx                 ; set length to -1
        dec     ecx                     ; ...
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     edi                     ; point to null character
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          mov   [edi],al                ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          je    short E_C_strcat1       ; - ...
          mov   al,1[esi]               ; - get next char
          add   esi,2                   ; - bump up pointer
          mov   1[edi],al               ; - copy it
          add   edi,2                   ; - bump up pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_C_strcat1:
        pop     edi                     ; restore destination address
        pop     es                      ; restore es
endb    C_strcat

defsb   FC_strcat
        db      "/* edi strcat( edi, esi ) zaps eax,ecx,esi */",0
        db      "#define FC_strcat_ret   HW_D( HW_EDI )",0
        db      "#define FC_strcat_parms P_EDI_ESI",0
        db      "#define FC_strcat_saves HW_NotD_3( HW_EAX, HW_ECX, HW_ESI )",0
        db      0
;
;       EDI strcat( EDI, ESI )
;       EAX,ECX and ESI are modified
;
beginb  FC_strcat
        push    edi                     ; save destination address
        sub     ecx,ecx                 ; set length to -1
        dec     ecx                     ; ...
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     edi                     ; point to null character
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          mov   [edi],al                ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          je    short E_FC_strcat1      ; - ...
          mov   al,1[esi]               ; - get next char
          add   esi,2                   ; - bump up pointer
          mov   1[edi],al               ; - copy it
          add   edi,2                   ; - bump up pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_FC_strcat1:
        pop     edi                     ; restore destination address
endb    FC_strcat

defsb   S_strcat
        db      "/* edi strcat( edi, esi ) zaps eax,esi */",0
        db      "#define S_strcat_ret   HW_D( HW_EDI )",0
        db      "#define S_strcat_parms P_EDI_ESI",0
        db      "#define S_strcat_saves HW_NotD_2( HW_EAX, HW_ESI )",0
        db      0
;
;       EDI strcat( EDI, ESI )
;       EAX and ESI are modified
;
beginb  S_strcat
        push    edi                     ; save destination address
        dec     edi                     ; back up one to start
        _loop                           ; loop (find end of first string)
          inc   edi                     ; - point to next byte
          cmp   byte ptr [edi],0        ; - check for null character
        _until  e                       ; until end of first string
        _loop                           ; loop (concatenate strings)
          lodsb                         ; - get char from src
          mov   [edi],al                ; - append to end of dest
          inc   edi                     ; - point to next byte
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        pop     edi                     ; restore destination string address
endb    S_strcat

defsb   Z_strcat
        db      "/* es:edi strcat( es:edi, ds:esi ) zaps eax,esi */",0
        db      "#define Z_strcat_ret   HW_D_2( HW_ES, HW_EDI )",0
        db      "#define Z_strcat_parms P_ESEDI_DSESI",0
        db      "#define Z_strcat_saves HW_NotD_2( HW_EAX, HW_ESI )",0
        db      0
;
;       ES:EDI strcat( ES:EDI, DS:ESI )
;       EAX and ESI are modified
;
beginb  Z_strcat
        push    edi                     ; save destination address
        push    ecx                     ; save ecx
        sub     ecx,ecx                 ; set length to -1
        dec     ecx                     ; ...
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        pop     ecx                     ; restore ecx
        dec     edi                     ; 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     edi                     ; restore destination string address
endb    Z_strcat

defsb   BD_strcat
        db      "/* es:edi strcat( es:edi, ds:esi ) zaps ecx,eax,esi */",0
        db      "#define BD_strcat_ret   HW_D_2( HW_ES, HW_EDI )",0
        db      "#define BD_strcat_parms P_ESEDI_DSESI",0
        db      "#define BD_strcat_saves HW_NotD_3( HW_ECX, HW_EAX, HW_ESI )",0
        db      0
;
;       ES:EDI strcat( ES:EDI, DS:ESI )
;       EAX,ECX and ESI are modified
;
beginb  BD_strcat
        push    edi                     ; save destination address
        sub     ecx,ecx                 ; set length to -1
        dec     ecx                     ; ...
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     edi                     ; point to null character
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          stosb                         ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          je    short E_BD_strcat1      ; - ...
          mov   al,1[esi]               ; - get next char
          add   esi,2                   ; - bump up pointer
          stosb                         ; - copy it
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_BD_strcat1:
        pop     edi                     ; restore destination address
endb    BD_strcat

defsb   DP_strcat
        db      "/* dx:eax strcat( dx:eax, cx:ebx ) zaps ecx,eax,esi */",0
        db      "#define DP_strcat_ret   HW_D_2( HW_DX, HW_EAX )",0
        db      "#define DP_strcat_parms P_DXEAX_CXEBX",0
        db      "#define DP_strcat_saves HW_NotD_3( HW_ECX, HW_ESI, HW_EDI )",0
        db      0
;
;       DX:EAX _fstrcat( DX:EAX, CX:EBX )
;       EAX,ECX,EDI and ESI are modified
;
beginb  DP_strcat
        push    ds                      ; save segment registers
        push    es                      ; ...
        push    eax                     ; save destination address
        mov     es,edx                  ; load segment registers
        mov     ds,ecx                  ; ...
        mov     esi,ebx                 ; get source offset
        mov     edi,eax                 ; get destination offset
        sub     ecx,ecx                 ; set length to -1
        dec     ecx                     ; ...
        mov     al,0                    ; scan for null character
        repnz   scasb                   ; ...
        dec     edi                     ; point to null character
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          stosb                         ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          je    short E_DP_strcat1      ; - ...
          mov   al,1[esi]               ; - get next char
          add   esi,2                   ; - bump up pointer
          stosb                         ; - copy it
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_DP_strcat1:
        pop     eax                     ; restore destination address
        pop     es                      ; restore segment registers
        pop     ds                      ; ...
endb    DP_strcat

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

defsb   C_strchr
        db      "/* esi strchr( esi, dl ) zaps eax,esi */",0
        db      "#define C_strchr_ret   HW_D( HW_ESI )",0
        db      "#define C_strchr_parms P_ESI_DL",0
        db      "#define C_strchr_saves HW_NotD_2( HW_EAX, HW_ESI )",0
        db      0
;
;       ESI strchr( ESI, DL )
;       EAX and ESI are modified
;
beginb  C_strchr
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          cmp   al,dl                   ; - quit if char found
          je    short E_C_strchr        ; - ...
          cmp   al,0                    ; - quit if end of string
          je    short E_C_strchr1       ; - ...
          inc   esi                     ; - increment pointer
          mov   al,[esi]                ; - get next char
          cmp   al,dl                   ; - quit if char found
          je    short E_C_strchr        ; - ...
          inc   esi                     ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_C_strchr1:
        sub     esi,esi                 ; return NULL
endb    C_strchr

defsb   S_strchr
        db      "/* esi strchr( esi, dl ) zaps eax,esi */",0
        db      "#define S_strchr_ret   HW_D( HW_ESI )",0
        db      "#define S_strchr_parms P_ESI_DL",0
        db      "#define S_strchr_saves HW_NotD_2( HW_EAX, HW_ESI )",0
        db      0
;
;       ESI strchr( ESI, DL )
;       EAX and ESI are modified
;
beginb  S_strchr
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          cmp   al,dl                   ; - quit if char found
          je    short E_S_strchr        ; - ...
          inc   esi                     ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        sub     esi,esi                 ; return NULL
endb    S_strchr

defsb   BD_strchr
        db    "/* dx:esi strchr( ds:esi, cl ) zaps dx,esi,eax */",0
        db    "#define BD_strchr_ret   HW_D_2( HW_DX, HW_ESI )",0
        db    "#define BD_strchr_parms P_DSESI_CL",0
        db    "#define BD_strchr_saves HW_NotD_3( HW_DX, HW_ESI, HW_EAX )",0
        db    0
;
;       DX:ESI strchr( DS:ESI, CL )
;       EAX,EDX and ESI are modified
;
beginb  BD_strchr
        mov     edx,ds                  ; save ds
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          cmp   al,cl                   ; - quit if char found
          je    short E_BD_strchr       ; - ...
          inc   esi                     ; - increment pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        sub     esi,esi                 ; return NULL
        sub     edx,edx                 ; ...
endb    BD_strchr

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

defsb   C_strcpy
        db    "/* edi strcpy( edi, esi ) zaps eax,esi */",0
        db    "#define C_strcpy_ret   HW_D( HW_EDI )",0
        db    "#define C_strcpy_parms P_EDI_ESI",0
        db    "#define C_strcpy_saves HW_NotD_2( HW_EAX, HW_ESI )",0
        db    0
;
;       EDI strcpy( EDI, ESI )
;       EAX and ESI are modified
;
beginb  C_strcpy
        push    edi                     ; save destination address
        _loop                           ; loop
          mov   al,[esi]                ; - get char from src
          mov   [edi],al                ; - store in output buffer
          cmp   al,0                    ; - quit if end of string
          je    short E_C_strcpy1       ; - ...
          mov   al,1[esi]               ; - get next char
          add   esi,2                   ; - bump up pointer
          mov   1[edi],al               ; - copy it
          add   edi,2                   ; - bump up pointer
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
E_C_strcpy1:
        pop     edi                     ; restore destination address
endb    C_strcpy

defsb   S_strcpy

⌨️ 快捷键说明

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