trap.asm

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

ASM
832
字号
                mov     di,cs
                mov     ds,di
                sub     di,di
                mov     es,di
                mov     si,offset SaveVects
                mov     cx,1024/2
                cli
                rep     movsw
                sti

                pop     cx              ; restore registers
                pop     dx
                pop     di
                pop     si
                pop     ds
                pop     es
                ret
FiniVectors_    endp



public          SetIntVecs_
SetIntVecs_     proc    near

                push    DS
                push    ES
                push    BX
                push    AX

                sub     AX,AX
                mov     ES,AX

                cli

        ife     dummy
                mov     BX,0004H                ; 1 * 4 = 4
                mov     AX,CS:TraceRtn
                mov     ES:[BX],AX
                mov     AX,CS
                mov     ES:2[BX],AX
        endif

                SetIntr  03H,BptTrap
                SetIntr  05H,UsrIntHandler
                SetIntr  15H,SysServHandler
                SetIntr  20H,ProgTerminate
                SwapIntr 28H,SaveBusyWait
                mov     ax,seg DGROUP
                mov     ds,ax
                cmp     byte ptr ds:_BoundAppLoading,0
                _if     ne
                SetIntr  21H,LoadOSHandler
                _else
                SetIntr  21H,OSHandler
                _endif
                SetIntr  27H,ProgTerminate

                sti

                pop     AX
                pop     BX
                pop     ES
                pop     DS

                jmp     near ptr SetUsrTask_

SetIntVecs_     endp


public          ClrIntVecs_
ClrIntVecs_     proc    near

                push    ES
                push    BX
                push    AX

                sub     AX,AX
                mov     ES,AX

                cli
                SetIntr  01H,NullHandler
                SetIntr  03H,NullHandler
                RestIntr 05H,PrgIntVec
                RestIntr 15H,SysServVec
                RestIntr 20H,PrgTermVec
                RestIntr 21H,OSIntVec
                RestIntr 27H,ResTermVec
                SwapIntr 28H,SaveBusyWait
                sti

                call    GetPSP
                mov     CS:CurrPSP,AX

                pop     AX
                pop     BX
                pop     ES

                jmp     near ptr SetDbgTask_

ClrIntVecs_     endp

                assume ds:nothing


SetBreak:       mov     byte ptr CS:UsrInt,-1
NullHandler:    iret


TimerHandler:
                pushf                   ; call old handler
                call    dword ptr TimerIntVec; ...
                cmp     byte ptr CS:UsrInt,0; check for requested interrupt
                je      NullHandler     ; quit if no interrupt requested
                push    ds              ; save DS
                push    bx              ; save BX
                lds     bx, CS:InDos    ; get InDos pointer
                cmp     byte ptr [bx],0 ; check if InDos is non-zero
                pop     bx              ; restore BX
                pop     ds              ; restore DS
                jne     NullHandler     ; quit if can't interrupt right now
DoIntTask:      mov     byte ptr CS:TrapType,TRAP_USER  ; user interrupt request
                mov     byte ptr UsrInt,0       ; clear pending request
                jmp     DebugTask


SysServHandler:
                cmp     AH,85H          ; is it a SysReq key press?
                je      UsrIntHandler   ; if so then handle the interrupt
                jmp     dword ptr SysServVec ; jump to old hander


UsrIntHandler:  mov     CS:UsrInt, -1   ; request user interrupt
                iret

ChkReturn:      mov     SS,CS:SaveIntSS
                mov     SP,CS:SaveIntSP
                pop     CS:SaveIntSP
                pop     CS:SaveIntSS
                push    BP                      ; save BP
                mov     BP,SP                   ; get access to stack
                push    AX                      ; save AX
                pushf                           ; save flags
                mov     AX,6[BP]                ; get old flags
                and     AX,0100H                ; isolate T-bit
                or      AX,-4[BP]               ; merge with new flags
                mov     6[BP],AX                ; save new flags
                pop     AX                      ; get rid of extra flags
                pop     AX                      ; restore AX
                pop     BP                      ; restore BP

                dec     byte ptr CS:DOSCount
                jne     rtrntouser
                cmp     byte ptr CS:UsrInt,00H
                jne     DoIntTask
rtrntouser:     iret


public          LoadOSHandler
LoadOSHandler:
                cmp     AH,48H                  ; if allocate memory request
                _if     e                       ; - then
                pushf                           ; - do the request
                push    cs
                call    near ptr OSHandler
                push    bp                      ; - save bp
                push    ax                      ; - save ax
                pushf                           ; - get flags register into ax
                pop     ax                      ; - ...
                mov     bp,sp                   ; - get addressability to stack
                mov     8[bp],ax                ; - zap the flags image
                pop     ax                      ; - restore ax
                _if     nc                      ; - if memory allocated
                push    ds                      ; - - save ds
                dec     ax                      ; - - point to DOS mem block
                mov     ds,ax                   ; - - ...
                inc     ax                      ; - - restore ax
                mov     bp,cs:_SegmentChain     ; - - link into our seg chain
                mov     ds:[14],bp              ; - - ...
                mov     cs:_SegmentChain,ds     ; - - ...
                pop     ds                      ; - - restore ds
                _endif                          ; - endif
                pop     bp                      ; - restore bp
                iret                            ; - return
                _else                           ; else
                cmp     ah,49H                  ; - if free memory request
                _if     e                       ; - - then
                push    ax                      ; - - save ax
                push    ds                      ; - - save ds
                mov     ax,es                   ; - - get segment
                dec     ax                      ; - - minus 1
                mov     es,ax                   ; - - ...
                cmp     ax,cs:_SegmentChain     ; - - if it's our chain head
                _if     e                       ; - - - then
                mov     ax,es:[14]              ; - - - bump head pointer up
                mov     cs:_SegmentChain,ax     ; - - - ...
                _else                           ; - - else
                mov     ax,cs:_SegmentChain     ; - - - h = SegmentChain
                _loop                           ; - - - loop
                mov     ds,ax                   ; - - - - if h->next == chunk
                mov     ax,es                   ; - - - - - then
                cmp     ds:[14],ax              ; - - - - - ...
                _if     e                       ; - - - - - ...
                mov     ax,es:[14]              ; - - - - - h->nex=h->nex->nex
                mov     ds:[14],ax              ; - - - - - ...
                                                ; - - - - - Z flag set !!!!!
                _else                           ; - - - - else
                mov     ax,ds:[14]              ; - - - - - head = hext->next
                test    ax,ax                   ; - - - - - test head,head
                _endif                          ; - - - - endif
                _until  e                       ; - - - until end of list
                _endif                          ; - - endif
                mov     ax,es                   ; - - restore es
                inc     ax                      ; - - ...
                mov     es,ax                   ; - - ...
                pop     ds                      ; - - restore ds
                pop     ax                      ; - - restore ax
                pushf                           ; - do the request
                push    cs                      ; - ...
                call    near ptr OSHandler      ; ...
                push    bp                      ; - save bp
                push    ax                      ; - save ax
                pushf                           ; - get flags register into ax
                pop     ax                      ; - ...
                mov     bp,sp                   ; - get addressability to stack
                mov     8[bp],ax                ; - zap the flags image
                pop     ax                      ; - restore ax
                pop     bp                      ; - restore bp
                iret                            ; - return
                _endif                          ; - endif
                _endif                          ; endif

OSHandler:
                cmp     AX,4B00H
                je      OSJmp
                cmp     AH,0
                je      ProgTerminate
                cmp     AH,31H
                je      ProgTerminate
                cmp     AH,4CH
                je      ProgTerminate


                inc     byte ptr CS:DOSCount
                push    CS:SaveIntSS
                push    CS:SaveIntSP
                mov     CS:SaveIntSS,SS
                mov     CS:SaveIntSP,SP
                pushf
                push    CS
                push    AX
                push    BP
                mov     BP,SP
                mov     AX,16[BP]
                and     AH,0FEH                         ; clear T-bit
                mov     6[BP],AX
                mov     AX,offset ChkReturn
                xchg    AX,2[BP]
                pop     BP

OSJmp:          jmp     dword ptr OSIntVec  ; jump to old handler


ProgTerminate:
                push    AX                      ; save AX
                call    GetPSP                  ; get the current PSP
                cmp     AX,CS:TaskPSP           ; is it the debugged task?
                pop     AX                      ; restore AX
                jne     OSJmp                   ; let DOS see it if another task
terminate:      push    BP                      ; save BP
                mov     BP,SP                   ; get access to stack
                push    BX                      ; save BX
                push    DS                      ; save DS
                lds     BX,2[BP]                ; get return offset/segment
                cmp     byte ptr -2[BX],0CDH    ; was it a software interrupt ?
                jne     not_an_int              ; if it was then
                sub     word ptr 2[BP],2        ; - backup return addr
not_an_int:     pop     DS                      ; restore DS
                pop     BX                      ; restore BX

⌨️ 快捷键说明

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