📄 trap-out.asm
字号:
; TRAPOUT2.ASM v2.0 by ARK (ark@lhq.com, root@ark.dyn.ml.org) 11-28-97
; Traps IN and OUT instructions in INT 10h and displays DX and AX/AL values.
;
; In the header "T DX/I AX/L", T is the Type of instruction (I=IN, O=OUT),
; DX/I is the value of DX or the Immediate value if port<256, and AX/L
; is the value of AX or AL depending on if an 8 or 16 bit value is listed.
; AX/L is meaningless for IN's since it is the value if AX/L *before* the
; call to IN.
;
; This is very useful to find information about how your video card works.
; I wrote this to get register dumps for my Trident TVGA9440AGi card so
; that I could use it under Linux.
;
; NOTE: Pipe the output or you won't see anything!
; (ex: TRAP-OUT 4F02 0101 > 640x480.256)
;
; New in v2.0:
; * Traces into INT 10 calls that are called from inside INT 10!
; * Allows AX and BX values to be specified!
; * Command line accepts trailing spaces now.
; x Code to trap INT's also! (T column='N', DX/I=INT ##, AX/L=AX value)
; (Its commented out - but you can recompile with it if you want)
;
; How to assemble with Borland:
; tasm /ml /zd ncr.asm (case sensitive, line number debug info only)
; tlink /x /t ncr.obj (no map, make com file)
;
.model tiny ; Tiny memory model, all segments point to the same 64K
.286 ; This code will run on a 286... actually, it
.code ; Everything is in the code segment(cs) will probably
.startup ; Startup run on anything
jmp Start ; Go to beginning of progam
realINT1 dd 52411A3Eh ; Address of original INT 01h routine offset
realINT10 dd 3C1B214Bh ; Memory for [es:bx] of the real INT 10h
; (defaults are '>-ARK!-<' just for looks in the .COM)
; strings
no_command_line db 'Use: TRAPOUT2 [AX] [BX]',13,10
db ' Traces all IN/OUT calls inside INT 10h',13,10,36
tracing db 'Tracing INT 10h with AX:',36
bx_msg db ' BX:',36
header db 13,10,'T DX/I AX/L',13,10,36
INT1 proc ; Interrupt Service Routine for Single Step Debugging
push ax ; save registers
push dx
push es
push di
push bp
mov bp,sp ; set bp to the stack
push word ptr cs:[bp+12] ; put the real cs
pop es ; into es
push word ptr cs:[bp+10] ; put the real ip
pop di ; into di
mov al,byte ptr es:[di] ; set al to the next instruction that will
; be executed after this INT 01 is done.
; This code will trap INT's also...
; cmp al,0CDh ; If al is not CD (INT) keep going
; jne not_int ; If it is, display some stuff...
;; This will skip doing the INT's...
;; add word ptr cs:[bp+10],2 ; Add 2 to the real ip, to skip the INT
; mov dl,4Eh ; Display an N
; mov ah,02h ; The immediate value/DX is the INT ##
; int 21h ; that is called. AX is the value before
; mov dl,20h ; Display a space
; mov ah,02h ;
; int 21h ; Display the immediate value which is
; jmp is_imm ; reallly the interrupt number called.
not_int:
and al,0F4h ; If al is E4-E7 or EC-EF (all IN/OUT's)
cmp al,0E4h ; Then we display our stuff
jne not_io ; Otherwise, do nothing
; note: 1 more byte of code after this
; jmp will make it out of range...
mov al,byte ptr es:[di] ; Set al to next instruction
test al,02h ; If bit 1 is set then we have an OUT
jz is_in ; If bit 1 is 0, we have an IN
mov dl,4Fh ; Display an O
mov ah,02h
int 21h
jmp dx_or_imd
is_in: ; Display an I
mov dl,49h
mov ah,02h
int 21h
dx_or_imd: ; Display a space
mov dl,20h
mov ah,02h
int 21h
mov al,byte ptr es:[di] ; Set al to next instruction
test al,08h ; If bit 3 is set then we are using DX
jz is_imm ; If bit 3 is 0, we are using an immediate
mov ax,[bp+6] ; restore dx to ax
call ShowHex ; Display dx
call ShowHex
call ShowHex
call ShowHex
jmp ax_or_al
is_imm:
mov dl,20h ; Display 2 spaces
mov ah,02h
int 21h
mov dl,20h
mov ah,02h
int 21h
mov ah,byte ptr es:[di+1] ; Set ah to byte after the next instruction
call ShowHex ; Display the immediate value
call ShowHex
ax_or_al:
mov dl,2Ch ; Display a comma
mov ah,02h
int 21h
mov al,byte ptr es:[di] ; Set al to next instruction
test al,01h ; If bit 0 is set then we are using AX
jz is_al ; If bit 0 is 0, we are using AL
mov ax,[bp+8] ; Restore ax
call ShowHex ; Display ax
call ShowHex
call ShowHex
call ShowHex
jmp print_next_line
is_al:
mov ah,[bp+8] ; Restore al to ah
call ShowHex ; Display al
call ShowHex
print_next_line:
mov dl,0Dh ; print a newline
mov ah,02h
int 21h
mov dl,0Ah
mov ah,02h
int 21h
not_io:
pop bp ; restore registers
pop di
pop es
pop dx
pop ax
iret ; end interrupt
INT1 endp
; INT 10h that fakes the real INT 10 and sets the trap flag.
INT10 proc ; Interrupt Service Routine for Tracing INT 10h
push ax ; Save AX
pushf ; Put flags on the stack
pop ax ; Then into AX
or ax,0100h ; Set the trap flag
push ax ; Trap Flag calls INT 01h between every instruction
popf ; Stuff new flags back into the flags register
pop ax ; Restore AX
cli ; Fake INT call: clear interrupt flag, skip clearing
pushf ; trap flag, push flags, call to location.
call cs:[realINT10] ; This call to INT 10h is be trapped for
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -