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

📄 ioisr.asm

📁 利用386保护模式将DOS实模式下的PC总线I/O操作(in/out)实时捕捉到内存并可以显示在屏幕上。可用于ISA/VESA/PCI插卡及相关软件的输入/输出调试、I/O性能/行为分析和反汇编。Ve
💻 ASM
📖 第 1 页 / 共 2 页
字号:
                add     di, 2                   ;past space and attribute
                cmp     di, VID_PAGE_SIZE
                jb      display_i100
                xor     di, di                  ;back to start of page
display_i100:
                mov     display_loc, di
                pop     es
                pop     ds
                popa
                ret
display_it      endp

put_hex_digit   proc    near
                push    ax
                mov     cx, 2                   ;2 digits in al
                mov     ah, al
put_hex_100:
                shr     al, 4
                cmp     al, 9
                ja      put_hex_200
                add     al, '0'
                jmp     short put_hex_300
put_hex_200:
                add     al, 'A' - 10
put_hex_300:
                cld
                stosb
                inc     di                      ;past attrib
                mov     al, ah
                shl     al, 4
                loop    put_hex_100
                pop     ax
                ret
put_hex_digit   endp

;--------------------------------------------------------------
;pass_thru - This procedure is JMPed to by any interrupt      |
;            handler which wishes to pass control to the      |
;            original ISR per the interrupt vector table.     |
;                                                             |
;            Entry:                                           |
;                  See stack_area struc for stack layout      |
;                  Any error code has been removed from stack.|
;                  EIP on stack has been adjusted if          |
;                  necessary.                                 |
;--------------------------------------------------------------
pass_thru       proc    near
                mov     bp, sp
                pushad
                push    ds
                mov     ax, offset gdt_seg:sel_databs
                mov     ds, ax                  ;address all base memory
                movzx   ebx, [bp].s_ss          ;user stack
                shl     ebx, 4                  ;make linear
                mov     edx, [bp].s_esp         ;user stack pointer
                sub     edx, 6                  ;flags, cs, ip
                mov     [bp].s_esp, edx         ;adjust it
                mov     eax, [bp].s_eflags      ;put on flags
                mov     [ebx][edx].user_flags, ax
;
;change flags on stack so that original ISR will be entered with
;interrupts cleared and trap flag cleared to be consistent with their
;state upon entering an ISR (the normal way).
;
                and     ax, not (TRAP_FLAG + INT_FLAG)
                mov     [bp].s_eflags, eax      ;put back flags
                mov     ax, [bp].s_cs           ;put on user cs
                mov     [ebx][edx].user_cs, ax
                mov     eax, [bp].s_eip         ;put on ip
                mov     [ebx][edx].user_ip, ax
                movzx   ebx, [bp].s_pushed_int  ;get int number
                movzx   eax, [ebx * 4].d_offset  ;offset portion
                mov     [bp].s_eip, eax
                mov     ax, [ebx * 4].d_segment  ;segment portion
                mov     [bp].s_cs, ax
                pop     ds
                popad
                add     sp, 2                   ;get rid of int number
                pop     bp
                iretd
pass_thru       endp

;--------------------------------------------------------------
;gen_prot_isr - JMP here if int 0dh.  Process as follows:     |
;                                                             |
;               Look for software int.  If found, go route to |
;               appropriate ISR.                              |
;                                                             |
;               Look for I/O instructions we currently        |
;               support.  If found, store port, size and      |
;               direction of I/O.  Also, set trap flag and    |
;               return (we will get control at int 1 to       |
;               inspect data).                                |
;                                                             |
;               If other than software int or I/O, go         |
;               display 0dh and halt.                         |
;                                                             |
;--------------------------------------------------------------
gen_prot_isr    proc    near
                push    ds
                pushad
                mov     bx, offset gdt_seg:sel_databs
                mov     ds, bx
                movzx   ebx, [bp].e_cs  ;get cs of user instruction
                shl     ebx, 4          ;make linear
                add     ebx, [bp].e_eip ;add ip
                mov     ax, [ebx]       ;get bytes at cs:ip
                cmp     al, INT_OPCODE
                jne     get_prot100
                inc     [bp].e_eip      ;get past the 0cdh
get_prot050:
                inc     [bp].e_eip
;
;Adjust stack so that error code goes away and int number retrieved from
;instruction goes in spot on stack where pushed int number is (for stacks
;with no error code).  Stack will be the way pass_thru routine likes it.
;
                mov     bx, [bp].e_pushed_bp
                shl     ebx, 16         ;get into high word
                mov     bl, ah          ;interrupt number
                mov     [bp].e_errcode, ebx
                popad
                pop     ds
                add     sp, 4           ;error code gone
                jmp     pass_thru
get_prot100:
                cmp     al, INT3_OPCODE
                jne     get_prot150
                mov     ah, 3           ;interrupt 3
                jmp     short get_prot050
get_prot150:

                mov     bx, offset gdt_seg:sel_data
                mov     ds, bx
                mov     bx, offset io_table
                mov     cx, IO_TAB_ENTRIES
get_prot200:
                cmp     al, [bx].io_opcode
                jne     get_prot300
                mov     trap_status, EXPECT_INT1
                mov     cl, [bx].io_info ;get info about instruction
                mov     access_info, cl
		test    cl, CONSTANT    ;is port number in instruction?
		jz      get_prot250     ;if not, we have it
		xchg    ah, al          ;ah = 2nd byte of instruction
		sub     ah, ah
		mov     dx, ax
get_prot250:
		mov     access_port, dx  ;save port
		and     cx, (AWORD OR ABYTE)   ;number of bits
                sub     ah, ah          ;indicate clear
                call    do_bit_map

                popad
                pop     ds
                or      [bp].e_eflags, TRAP_FLAG ;single step i/o

                add     sp, 2           ;int number pushed
                pop     bp
                add     sp, 4           ;error code
                iretd

get_prot300:
                add     bx, size io_struc ;advance to next table entry
                loop    get_prot200
                mov     ax, [bp].e_cs   ;get cs of user instruction
                call    display_it
                mov     eax, [bp].e_eip ;add ip
                call    display_it
                popad
                pop     ds
                mov     ax, [bp].e_pushed_int
                jmp     fatal_error
gen_prot_isr    endp

;--------------------------------------------------------------
;do_bit_map - For the number of ports specified, clear/set    |
;             corresponding I/O permission map bits.          |
;                                                             |
;             Enter:  Ah = 0 clear, ah = 1 set                |
;                     dx = starting port                      |
;                     cx = number of ports                    |
;                                                             |
;  All registers saved.                                       |
;--------------------------------------------------------------
do_bit_map      proc    near
                push    ax
                push    bx
                push    cx
                push    dx
                push    ds
                mov     bx, offset gdt_seg:sel_tss_alias
                mov     ds, bx
                assume  ds:tss_seg
                mov     bx, t_iomap
                push    cx
                mov     cx, dx                  ;port
                and     cl, 7                   ;get non byte boundary
                mov     al, 1                   ;first bit position
                shl     al, cl                  ;get out corresponding bit
                shr     dx, 3                   ;start_port/8
                pop     cx
                add     bx, dx                  ;starting offset in map
do_bit100:
                or      ah, ah
                jnz     do_bit200
                mov     dl, al
                not     dl
                and     byte ptr [bx], dl       ;turn off permission bit
                jmp     short do_bit250
do_bit200:
                or byte ptr [bx], al            ;turn on permission bit
do_bit250:
                rcl     al, 1                   ;next bit position
                jnc     do_bit300
                inc     bx
                rcl     al, 1
do_bit300:
                loop    do_bit100
                pop     ds
                pop     dx
                pop     cx
                pop     bx
                pop     ax
                ret
do_bit_map      endp

;--------------------------------------------------------------
;user_int_isr - return buffer address to caller.              |
;                                                             |
;             Exit: dx:bx= far ptr to io_buf		      |
;                   ah = total count of data wrap             |
;                   al = buffer size (KB)	              |
;                   cx = offset of the start of data          |
;--------------------------------------------------------------
user_int_isr    proc    near
		mov     dx, data
		mov     bx, offset data:io_buf
		push    ds
		mov     ds,dx
		assume  ds:data
		mov     cx, io_buf_ptr
		mov	ax, BUF_SIZE
		shr	ax, 10				; size in KB
		mov     ah, io_buf_wrap
		pop     ds
		iret
user_int_isr    endp
isrcode         ends
                end

⌨️ 快捷键说明

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