⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioisr.asm

📁 利用386保护模式将DOS实模式下的PC总线I/O操作(in/out)实时捕捉到内存并可以显示在屏幕上。可用于ISA/VESA/PCI插卡及相关软件的输入/输出调试、I/O性能/行为分析和反汇编。Ve
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;---------------------------------------------------------------
;ioisr - Interrupt Service Routines for I/O Monitor            |
;--------------------------------------------------------------|
;Copyright 1991 ASMicro Co.                                    |
;--------------------------------------------------------------|
; 5/25/91                      Rick Knoblaugh                  |
;--------------------------------------------------------------|
;include files                                                 |
;---------------------------------------------------------------
                .386P
                include ioequ.inc
                include iomac.inc
                include iostruc.inc


data            segment para public 'data16' use16
		extrn   start_port:WORD
		extrn   end_port:WORD
		extrn   old_int1:DWORD
		extrn   old_user_int:DWORD
		extrn   io_table:BYTE
		extrn   IO_TAB_ENTRIES:ABS
		extrn   access_port:word
		extrn   access_info:byte
		extrn   io_buf:byte
		extrn   io_buf_end:ABS
		extrn   io_buf_ptr:word
		extrn   io_repeat_ptr:word	; buffer ptr to save repeat data
		extrn   io_buf_wrap:byte	; count buffer wrapped
		extrn   display_loc:word
                extrn   trap_status:byte
data            ends

gdt_seg         segment para public 'data16' use16
                extrn   sel_databs:byte
                extrn   sel_video:byte
                extrn   sel_data:byte
                extrn   sel_tss_alias:byte
gdt_seg         ends

tss_seg         segment para public 'data16' use16
tss_seg         ends


isrcode         segment para public 'icode16' use16
                assume cs:isrcode, ds:nothing, es:nothing
;--------------------------------------------------------------
;PUBLICS                                                      |
;--------------------------------------------------------------
                public  int1_isr
                public  user_int_isr
                public  int_0
                public  int_2
                public  int_3
                public  int_4
                public  int_5
                public  int_6
                public  int_7
                public  except_8
                public  except_9
                public  except_0ah
                public  except_0bh
                public  except_0ch
                public  except_0dh
                public  except_0eh
                public  except_0fh
                public  int_20h
                public  int_21h
                public  int_22h
                public  int_23h
                public  int_24h
                public  int_25h
                public  int_26h
                public  int_27h

                public  int_70h
                public  int_71h
                public  int_72h
                public  int_73h
                public  int_74h
                public  int_75h
                public  int_76h
                public  int_77h

        irp     z, <0, 2, 3, 4, 5, 6, 7>
        DOINT   &z
        endm

        irp     z, <8, 9, 0ah, 0bh, 0ch, 0dh, 0eh, 0fh>
        DOEXCP  &z
        endm

        irp     z, <20h, 21h, 22h, 23h, 24h, 25h, 26h, 27h>
        DOEXCPH &z
        endm

        irp     z, <70h, 71h, 72h, 73h, 74h, 75h, 76h, 77h>
        DOINT   &z
        endm

;--------------------------------------------------------------
;int1_isr -  ISR for single step interrupt.  If trap_status   |
;            has EXPECT_INT1 bit set, this is the trap        |
;            that occurs just after the I/O instruction       |
;            we are monitoring executes.  Store the I/O data  |
;            from ax into our buffer.                         |
;--------------------------------------------------------------
int1_isr        proc    far
                push    bp
                mov     bp, sp
                push    bx
                push    ds
                mov     bx, offset gdt_seg:sel_data
                mov     ds, bx
                assume  ds:data
                test    trap_status, EXPECT_INT1 ;expecting an int 1?
                jnz     int1_050
                pop     ds
                pop     bx
                push    1
                jmp     pass_thru               ;if not, do old int 1
int1_050:

		push    ax
		push    cx
		push    dx
		mov     trap_status, 0
		and     [bp].s_eflags, NOT TRAP_FLAG ;no more single step

		mov     dx, access_port
		mov     cl, access_info
		test    cl, AWORD               ;word access?
		jnz     test_out_flag

		sub     ah, ah                  ;if not, clear upper byte
		or	dx, PORT_BYTE		;single byte I/O

test_out_flag:	test	cl, OUTPUT
		jz	get_last_dat
		or	dx, PORT_OUTPUT		;write port

get_last_dat:	mov     bx, io_buf_ptr
		mov	[bx].io_data, 0		;initialize repeat count

save_buf_write:	mov	io_repeat_ptr, bx	;may save repeat data here

get_last_off:	sub     bx, size io_record	;find last buf ptr
		cmp     bx, offset io_buf	;buf start?
		jnb	check_last_dat
		mov	bx, io_buf_end - size io_record

check_last_dat: cmp	[bx].io_port, PORT_REPEAT
		jne	compare_port		;until real data found

		cmp	[bx].io_data, -1	;if repeat count full
		je	get_last_off            ;do not increase this count
		jmp	save_buf_write		;else increase this count

compare_port:	cmp	[bx].io_port, PORT_INVALID
		je	store_new_data		;no more wrapped history

		cmp	[bx].io_port, dx
		jne	store_new_data		;not the same port

		cmp	[bx].io_data, ax
		jne	store_new_data		;not the same data

		mov     bx, io_repeat_ptr	;repeated port I/O
		mov     dx, PORT_REPEAT		;flagging a repeat data
		mov	ax, [bx].io_data	;load last repeat count
		inc	ax			;increase repeat count
		jmp	store_data

store_new_data: mov	bx, io_buf_ptr		;set current ptr position

store_data:	mov     [bx].io_port, dx	;store port number
		mov     [bx].io_data, ax

		cmp	bx, io_buf_ptr	       	;if inc an old repeat
		jne	set_IOPM		;skip advance buffer

		add     bx, size io_record	;advance buf ptr
		cmp     bx, io_buf_end - size io_record  ;at end?
		jbe	next_buf

		mov     bx, offset io_buf	;wrap to buf start
		inc     io_buf_wrap		;wrap count++

next_buf:	mov     io_buf_ptr, bx          ;save new ptr

set_IOPM:	and     cx, (AWORD OR ABYTE)    ;number of port bits
                mov     ah, 1                   ;indicate set
                mov     dx, access_port
                call    do_bit_map      ;set the bits again

		pop     dx
		pop     cx
		pop     ax
		pop     ds
		pop     bx
		pop     bp
		iretd

int1_isr        endp

;--------------------------------------------------------------
;except_handler - Process as follows:                         |
;                                                             |
;                      Int 0dh - Go look for software int or  |
;                                I/O instruction.             |
;                    Any other                                |
;                    exception - go display exception number  |
;                                and halt.                    |
;--------------------------------------------------------------
except_handler  proc    near
                mov     bp, sp
                cmp     [bp].e_pushed_int , GEN_PROT_EXCEP
                je      gen_prot_isr
                mov     ax, [bp].e_pushed_int ;int in ax, go display
                jmp short fatal_error
except_handler  endp

fatal_error     proc    near
                call    display_it
                jmp     $
fatal_error     endp

;--------------------------------------------------------------
;display_it - Display hex number on screen at next display    |
;             offset.                                         |
;                                                             |
;             Enter:  number in AX                            |
;                     processor in protected mode             |
;                                                             |
;             All registers saved                             |
;--------------------------------------------------------------
display_it      proc    near
                pusha
                push    ds
                push    es

                mov     dx, offset gdt_seg:sel_data
                mov     ds, dx                  ;get our data segment
                assume  ds:data
                mov     dx, offset gdt_seg:sel_video
                mov     es, dx                  ;and video segment
                mov     di, display_loc
                xchg    al, ah                  ;print MSB first
                call    put_hex_digit
                xchg    al, ah                  ;get LSB
                call    put_hex_digit

⌨️ 快捷键说明

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