📄 dbgtrap.asm
字号:
push DS ; save DS
lds BX,dword ptr CS:SaveRegs; point to register save area
mov [BX].RES,ES ; save ES
mov [BX].RSI,SI ; SI
mov [BX].RCX,CX ; CX
mov [BX].RAX,AX ; CX
save_rest:
call ClrIntVecs_
sti ; enable interrupts
mov [BX].RDX,DX ; DX
mov [BX].RDI,DI ; DI
mov [BX].RBP,BP ; BP
mov [BX].RSS,SS ; SS
pop [BX].RDS ; save DS
pop [BX].RBX ; save BX
pop [BX].RIP ; save IP
pop [BX].RCS ; save CS
pop [BX].RFL ; save flags
mov [BX].RSP,SP ; SP
xor SI,SI ; zero out high parts of 32 bit registers
mov [BX]._EAX,SI ; ...
mov [BX]._EBX,SI ; ...
mov [BX]._ECX,SI ; ...
mov [BX]._EDX,SI ; ...
mov [BX]._ESI,SI ; ...
mov [BX]._EDI,SI ; ...
mov [BX]._ESP,SI ; ...
mov [BX]._EBP,SI ; ...
mov [BX]._EIP,SI ; ...
mov [BX]._EFL,SI ; ...
mov byte ptr CS:AreWatching,0; we aren't watching anymore
jmp EnterDebugger ; enter the debugger
; DX:AX has load regs pointer & CX:BX has save regs pointer
public ExitDebugger
ExitDebugger:
mov CS:SaveRegs+0,BX; save save regs pointer
mov CS:SaveRegs+2,CX; . . .
mov SI,AX ; get pointer to the current reg set
mov DS,DX ; . . .
test byte ptr 27[SI],1;are we trace trapping?
je not_watch ; - quit if not
mov DI,CS:TraceRtn
cmp DI,offset _text:WatchTrap; - are we watch trapping?
je watching ; - quit if not
cmp DI,offset _text:WatchTrap386; - are we watch trapping?
je watching ; - quit if not
jmp short not_watch ;
watching:
mov byte ptr CS:AreWatching,0ffH; - indicate watch points
not_watch:
cli ; interrupts off
mov SS,[SI].RSS ; get their SS
mov SP,[SI].RSP ; and their SP
sti ; interrupts on
mov AX,[SI].RAX ; AX
mov BX,[SI].RBX ; BX
mov CX,[SI].RCX ; CX
mov DX,[SI].RDX ; DX
mov DI,[SI].RDI ; DI
mov BP,[SI].RBP ; BP
mov ES,[SI].RES ; ES
push [SI].RFL ; flags
push [SI].RCS ; CS
push [SI].RIP ; IP
push [SI].RDS ; DS
mov SI,[SI].RSI ; SI
pop DS ; restore DS
cli ; interrupts off
call SetIntVecs_
cmp byte ptr CS:AreWatching,0; check for watch points
jnz WatchTrap ; check watch points first (for software ints)
iret ; return to user's program
watch_trap: ; we have a watch point trap
lds BX,dword ptr CS:SaveRegs; point at save area
mov byte ptr CS:TrapType,TRAP_WATCH_POINT
jmp save_rest ; save rest of the registers & enter debugger
WatchRestart: ; restart a watch point after a soft int
push BP ; save BP
mov BP,SP ; get access to stack
push AX ; save AX
pushf ; put flags into AX
pop AX ; . . .
mov 6[BP],AX ; update flags image
pop AX ; restore AX
pop BP ; restore BP
jmp short WatchTrap ; go do rest of watch point
WatchTrap386: ; we have a watchpoint trap
push AX ; save AX
db 00FH,021H,0F0H ; mov eax,dr6
test ax,0A00FH ; check if exception or break
pop AX ; restore AX
je WatchTrap ;
jmp TraceTrap386 ;
WatchTrap: ; we have a watchpoint trap
push BX ; save BX
push DS ; save DS
do_watch:
sti ; enable interrupts
lds BX,dword ptr CS:SaveRegs; get save area
; NYI- this could be fine tuned
mov [BX].RAX,AX ; save CX
mov [BX].RCX,CX ; save CX
mov [BX].RSI,SI ; save SI
mov [BX].RES,ES ; save ES
lds SI,dword ptr CS:WatchTbl; get address of watch point table
mov CX,CS:WatchCnt ; get number of watch points
start_loop: ; loop
les BX,WP_ADDR[SI] ; - get address of watch point
mov AX,ES:[BX] ; - get low order word
cmp AX,WP_VALUE[SI] ; - compare with entry in table
jne watch_trap ; - set watchpoint trap if different
mov AX,ES:2[BX] ; - get high order word
cmp AX,WP_VALUE+2[SI];- compare with entry in table
jne watch_trap ; - set watchpoint trap if different
add SI,WP_SIZE ; - point to next entry
loop start_loop ; until --CX = 0
lds BX,dword ptr CS:SaveRegs; point at save area
mov ES,[BX].RES ; restore ES
mov SI,[BX].RSI ; restore SI
mov CX,[BX].RCX ; restore CX
mov AX,[BX].RAX ; restore CX
mov BX,SP ; get pointer to interrupt stack frame
or byte ptr SS:9[BX],1; make sure the T-bit is on
lds BX,SS:4[BX] ; get return offset and segment
mov BX,[BX] ; get instruction and byte following it
cmp BL,0CDH ; is instruction a software interrupt?
cli ; interrupts off
je soft_int ; handle software interrupt
cmp BL,0CCH ; is it a break point instruction?
je brk_point ; handle breakpoint
cont2:
pop DS ; restore DS
pop BX ; restore BX
iret ; continue execution
soft_int: ; software interrupt routine
; simulate sofware interrupt action
push BP ; save BP
mov BP,SP ; get pointer to stack frame
add word ptr 6[BP],2; add two to the return address
mov BL,BH ; convert interrupt number to offset
sub BH,BH ; . . .
shl BX,1 ; . . .
shl BX,1 ; . . .
push 4[BP] ; save old BX
push 2[BP] ; save old DS
push 0[BP] ; save old BP
push AX ; save AX
sub BP,6 ; point at old BP again
sub AX,AX ; get access to interrupt vector table
mov DS,AX ; . . .
mov AX,0[BX] ; get interrupt offset
mov 06H[BP],AX ; new return offset is handler routine
mov AX,2[BX] ; get interrupt segment
mov 08H[BP],AX ; new return segment is handler routine
mov AX,010H[BP] ; get original flags
and AX,0fcffH ; turn off T,I bits
mov 0aH[BP],AX ; set new flags word
pop AX ; restore AX
pop BP ; restore BP
shr BX,1 ; convert offset back to interrupt number
shr BX,1 ; . . .
call ChkInt ; do we want to watch this interrupt?
jc abort_watch ; restart watch point routine if so
jmp do_watch ; . . .
abort_watch:
; we want the soft interrupt handler to return to the WatchTrap
; routine so that it can start watch pointing again
pop DS ; restore DS
pop BX ; restore BX
sub SP,6 ; allocate new frame
push BP ; save BP
mov BP,SP ; get access to stack
push AX ; save AX
mov AX,0CH[BP] ; transfer flags
mov 06H[BP],AX ; to new stack frame
mov AX,0AH[BP] ; transfer code seg
mov 04H[BP],AX ; to new stack frame
mov AX,08H[BP] ; transfer instr pointer
mov 02H[BP],AX ; to new stack frame
mov 0aH[BP],CS ; set code segment for soft int stack frame
mov AX,offset _text:WatchRestart; set intstruction pointer for
mov 08H[BP],AX ; int stack frame
pop AX ; restore AX
pop BP ; restore BP
iret ; execute soft int handler
brk_point: ; next instruction is a break point
pop DS ; restore DS
pop BX ; restore BX
mov byte ptr CS:TrapType,TRAP_BREAK_POINT ; we have a brk point trap
jmp DebugTask ; enter the debugger
_text ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -