int21win.asm

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

ASM
492
字号
        push    bx                      ; save bx
        push    cx                      ; save cx
        mov     bx,_Int21Selector       ; get 16-bit alias selector
        add     edx,_DataSelectorBase   ; add in BaseAddr
        push    edx                     ; transfer to cx:dx
        pop     dx                      ; ...
        pop     cx                      ; ...
        mov     ax,7                    ; set 'segment base address'
        int     31h                     ; ...
        mov     ds,bx                   ; set ds = 16-bit alias selector
        sub     dx,dx                   ; offset 0
        pop     cx                      ; restore cx
        pop     bx                      ; restore bx
        pop     ax                      ; restore ax
        int     21h                     ; issue int 21h
        pop     ds                      ; restore ds
        jc      short done_int21        ; exit if error
        movzx   eax,ax                  ; zero extend length of read/write
        jmp     short exit_int21        ; and exit

;
;       EDX contains a pointer
;
C_EDX_EDI:                              ; pointers in EDX, EDI need translated
C_EDX:                                  ; translate pointer in EDX
        pop     bx                      ; restore bx
        or      edx,edx                 ; check for NULL pointer
        jne     short not_null          ; ...
        push    ds                      ; save ds
        mov     ds,dx                   ; set ds:dx to NULL
        int     21h                     ; do int 21
        pop     ds                      ; restore ds
        jmp     short done_int21        ; and exit
;
;       EDX points to a filename
;
not_null:
        push    ds                      ; save ds
        push    edx                     ; save edx
        push    bp                      ; save bp
        push    ax                      ; save ax
        push    si                      ; save si
        push    0                       ; push a NULLCHAR for end of buffer
        mov     bp,sp                   ; point to stack frame
        sub     sp,256                  ; allocate local buffer
        mov     si,sp                   ; point to buffer
        call    docopy                  ; copy buffer from edx to stack
        mov     ax,4[bp]                ; restore function code
        cmp     ah,56h                  ; if rename function
        jne     not_rename              ; then
          mov   edx,edi                 ; - get address of second argument
          mov   di,si                   ; - save address of copied argument
          call  docopy                  ; - copy it to stack
          push  ss                      ; - set es=ss
          pop   es                      ; - ...
not_rename:                             ; endif
        mov     dx,sp                   ; point to local buffer
        mov     si,2[bp]                ; restore registers
        mov     ax,4[bp]                ; restore function code
        push    ss                      ; set ds=ss
        pop     ds                      ; ...
        int     21h                     ; do int 21
        lea     sp,6[bp]                ; clean up stack
        pop     bp                      ; restore bp
        pop     edx                     ; restore edx
        pop     ds                      ; restore ds

done_int21:
;
;       must not modify any registers or the condition codes
;
        movsx   eax,ax                  ; sign-extend value in ax
exit_int21:
        mov     ss,_StackSelector       ; switch back to 32-bit stack
        mov     esp,_SaveSP             ; ...
        mov     es,_DataSelector        ; reload 32-bit data selector
        mov     ds,_DataSelector        ; ...
        db      66h                     ; return to 32-bit code
        ret                             ; ...

C_SETDTA:                               ; set DTA address
        pop     bx                      ; restore bx
        mov     _DTA_Addr,edx           ; save DTA address
        jmp     short done_int21        ; and exit

C_GETCWD:                               ; get current directory
        pop     bx                      ; restore bx
        push    esi                     ; save 32-bit pointer
        push    bp                      ; save bp
        mov     bp,sp                   ; get access to stack
        sub     sp,128                  ; allocate buffer (only 64 req'd)
        mov     si,sp                   ; point to buffer
        push    ds                      ; save ds
        push    ss                      ; set ds=ss
        pop     ds                      ; ...
        int     21h                     ; issue int 21
        pop     ds                      ; restore ds
        _if     nc                      ; if no error
          mov   esi,2[bp]               ; - get 32-bit pointer
          mov   es,_DataSelector        ; - point to 32-bit segment
          mov   bp,sp                   ; - point to buffer
          push  ax                      ; - save ax
          _loop                         ; - loop (copy cwd to 32-bit buffer)
            mov   al,[bp]               ; - - get character
            inc   bp                    ; - - advance pointer
            mov   es:[esi],al           ; - - store character
            inc   esi                   ; - - advance pointer
            cmp   al,0                  ; - - check for end of string
          _until  e                     ; - until done
          pop   ax                      ; - restore ax
          mov   bp,sp                   ; - point bp to right place
          add   bp,128                  ; - ...
          clc                           ; - clear carry
        _endif                          ; endif
        mov     sp,bp                   ; restore stack
        pop     bp                      ; restore bp
        pop     esi                     ; restore esi
        jmp     short done_int21        ; and exit

C_FIND:                                 ; find first/find next
        pop     bx                      ; restore bx
        push    ecx                     ; save ecx (attribute)
        push    edx                     ; save edx (filename address)
        push    edi                     ; save edi
        push    esi                     ; save esi
        mov     esi,_DTA_addr           ; get addr of 32-bit DTA
        lea     di,_DTA_Area            ; point to local DTA
        push    cx                      ; save attribute
        mov     cx,DTA_SIZE             ; get size of DTA
        push    ax                      ; save ax
        _loop                           ; loop
          mov   al,es:[esi]             ; - get byte from 32-bit
          inc   esi                     ; - ...
          mov   [di],al                 ; - store in local DTA
          inc   di                      ; - ...
          dec   cx                      ; - decrement count
        _until  e                       ; until done
        push    dx                      ; save dx
        lea     dx,_DTA_Area            ; point to local DTA
        mov     ah,1Ah                  ; set DTA to local DTA
        int     21h                     ; ...
        pop     dx                      ; restore dx
        pop     ax                      ; restore ax
        pop     cx                      ; restore cx (attribute)
        cmp     ah,4Eh                  ; if find first
        _if     e                       ; then
          push  ds                      ; - save ds
          push  bp                      ; - save bp
          push  0                       ; - push nullchar
          mov   bp,sp                   ; - point to stack frame
          sub   sp,256                  ; - allocate local buffer
          mov   si,sp                   ; - point to buffer
          call  docopy                  ; - copy name from edx to stack
          mov   dx,sp                   ; - point to filename
          push  ss                      ; - set ds=ss
          pop   ds                      ; - ...
          mov   ah,4Eh                  ; - set find first
          int   21h                     ; - issue interrupt
          mov   sp,bp                   ; - clean up stack
          pop   bp                      ; - pop 0
          pop   bp                      ; - restore bp
          pop   ds                      ; - restore ds
        _else                           ; else find next
          int   21h                     ; - issue interrupt
        _endif                          ; endif
        pushf                           ; save flags
        mov     esi,_DTA_addr           ; get addr of 32-bit DTA
        lea     di,_DTA_Area            ; point to local DTA
        mov     cx,DTA_SIZE             ; get size of DTA
        push    ax                      ; save ax
        _loop                           ; loop
          mov   al,[di]                 ; - get byte from local DTA
          inc   di                      ; - ...
          mov   es:[esi],al             ; - copy to 32-bit DTA
          inc   esi                     ; - ...
          dec   cx                      ; - decrement count
        _until  e                       ; until done
        pop     ax                      ; restore ax
        popf                            ; restore flags
        pop     esi                     ; restore esi
        pop     edi                     ; restore edi
        pop     edx                     ; restore edx
        pop     ecx                     ; restore ecx
        jmp     done_int21              ; and exit

;
;       ESI contains a pointer
;
C_EOPEN:                                ; extended file open/create
        pop     bx                      ; restore bx
        or      esi,esi                 ; check for NULL pointer
        jne     short esi_not_null      ; ...
        push    ds                      ; save ds
        mov     ds,si                   ; set ds:si to NULL
        int     21h                     ; do int 21
        pop     ds                      ; restore ds
        jmp     done_int21              ; and exit
;
;       ESI points to a filename
;
esi_not_null:
        push    ds                      ; save ds
        push    esi                     ; save esi
        push    edx                     ; save edx
        push    bp                      ; save bp
        push    ax                      ; save ax
        push    0                       ; push a NULLCHAR for end of buffer
        mov     edx,esi                 ; get address of filename
        mov     bp,sp                   ; point to stack frame
        sub     sp,256                  ; allocate local buffer
        mov     si,sp                   ; point to buffer
        call    docopy                  ; copy buffer from edx to stack
        mov     ax,2[bp]                ; restore function code
        mov     si,sp                   ; point to local buffer
        mov     dx,6[bp]                ; restore registers
        push    ss                      ; set ds=ss
        pop     ds                      ; ...
        int     21h                     ; do int 21
        lea     sp,4[bp]                ; clean up stack
        pop     bp                      ; restore bp
        pop     edx                     ; restore edx
        pop     esi                     ; restore esi
        pop     ds                      ; restore ds
        jmp     done_int21              ; and exit

__Int21_ endp

docopy  proc    near
        _loop                           ; loop
          cmp   si,bp                   ; - quit if at end of local buffer
          _quif e                       ; - ...
          mov   ax,es:[edx]             ; - get 2 characters
          mov   ss:[si],ax              ; - copy to local buffer
          add   edx,2                   ; - increment pointer
          add   si,2                    ; - ...
          cmp   ah,0                    ; - quit if end of string
          _quif e                       ; - ...
          cmp   al,0                    ; - check for end of string
        _until  e                       ; until end of string
        ret                             ; return
docopy  endp


_TEXT   ends
        end

⌨️ 快捷键说明

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