以下是代码,有问题欢迎提出讨论
程式是com格式
masm 5.x
masm dbug.asm
link dbug.asm
exe2bin dbug.exe
masm6.x
ml/AT dbug.asm
程序代码:
.286
scan_key equ 44h ;f10
cseg segment
assume cs:cseg,ds:cseg,es:cseg
org 100h
begin: jmp INIT
OLD09_OFF DW 0
OLD09_SEG DW 0
old1C_off dw 0
old1C_seg dw 0
main_file db '',0
main_file1 db 'debug.exe',0
keep_ss dw 0
keep_sp dw 0
pcb dw 0,12 dup (0)
align 2
SendBuffer db (80 + 20)*2 dup (0)
OverwriteStr db 16 dup (0) ;max FFFF FFFF
lineBuffer db 82 dup (0) ;1 line
clear_len equ $ - offset SendBuffer
HexprocTable dw offset BtoH,offset DtoH,offset HtoD
Lastpos dw 0
firstpos dw 0
startpos dw 0
hexTable db '0123456789ABCDEF'
hex_table db 08,22,'084C2A6E195D3B7Fabcdef' ;max,comp lenght,data
work_flag db 0 ;int9工作中标志
work_flag1 db 0 ;int1ch工作中标志
userinput dd 0
ScanTable db 30h,0bh,31h,02h,32h,03h,33h,04h,34h,05h,35h,06h,36h,07h,37h,08h
db 38h,09h,39h,0ah,41H,1EH,42H,30H,43H,2EH,44H,20H,45H,12H,46H,21H
Sendflag db 0
;SendCount dw 0
LastSendAddr dw 0
argc db 0
argv dw 5 dup (?)
userprogram db 60 dup (0)
;------------------------------------------------------------------------------
NEW_INT09:
STI
pushf
push ax
cmp cs:work_flag,0 ;工作中?
jnz not_key ;对,走
in al,060h
push ax
in al,061h
or al,080h
out 061h,al
and al,07fh
out 061h,al
mov al,020h
out 020h,al
pop ax
cmp al,scan_key ;是否约定键
jnz not_key ;不
cmp sendFlag,1 ;送完key没?
jz not_key ;未完,不处理
mov cs:work_flag,1 ;设定工作中标志
call mainhex ;主程序
mov cs:work_flag,0 ;清除工作中标志
pop ax
popf
iret ;直接返回
not_key:pop ax
popf
jmp dword ptr cs:old09_off ;返回原来int9
;------------------------------------------------------------------------------
mainhex:push ds
push es
pusha
mov ax,cs
mov ds,ax
mov es,ax
;------ 初始化 开始-----
xor bp,bp
mov word ptr userinput,bp
mov word ptr userinput+2,bp
cld
mov di,offset SendBuffer
mov al,0
mov cx,clear_len ;SendBuffer 至 lineBuffer
rep stosb ;完后di指向lineBuffer尾
;------ 初始化 完结-----
sub di,2 ;指向lineBuffer尾之前2bytes
mov cx,80 ;最长一列80bytes
;mov bx,0
call GetCur ;get cursor posion , dh=row, dl=column
mov Lastpos,dx ;光标最后位置
mov bl,0 ;D和B的累加,初始化
m10: call SetCurPos ;设定光标位置
call GetChAtr ;读取该位置字节(al)
mov ah,al
cmp ah,',' ; 是否[,]
jz m60 ;是则找到源头
cmp ah,20h ;空白?
jnz m15 ;不是
or bl,bl ;bl是否0
jnz m60 ;bl不是0,即找到d或b后的第一空白
m15: and ah,5fh ;转大写
cmp ah,'D' ;D ?
jnz m20 ;不
or bp,2 ;D则设定BIT1
jmp short m25
m20: cmp ah,'H'
jnz m22
or bp,4 ;H则设定BIT2
jmp short m26
m22: cmp ah,'B' ;是否B
jnz m30 ;不
or bp,1h ;B则设定BIT0
m25: test bp,4 ;是否有h
jnz m28 ;有,跳过al不设0
m26: mov al,0 ;B或D到此,AL设0,用以清除该D或B的字符
m28: ; h , d , b到此
cmp byte ptr [di+1],20h
jz m29
cmp byte ptr [di+1],0
jz m29 ;jmp m100
test bp,4 ;是否有h ;和上面代码重复,未修正!
jz m35 ;没有h,不许有其他字符在后
m29: ;h , d, b之后必须为空白或0,否则离开
inc bl ;累加D或B或H
m30: mov [di],al ;清除该D或B或H的字符
dec di ;缓冲移前一位
dec dl ;光标移前一位
jns m40 ;若DL=0(光标位置0,再减则负)
m35: jmp m100 ;过了头,仍找不到[,] 走
m40: loop m10 ;下一字符
m60: ;到了[,]或空白位置
test bp,0000000000000100b ;是否有H
jz m61 ;否
mov bp,0000000000000100B ;给值4
jmp short m62 ;不比较BL个数(可能有B,D等16进制的字符)
m61: dec bl ;若只有1个b或b,bl=1,dec bl,等于0则输入正常
jnz m100
m62: inc dl
mov firstpos,dx ;[,]之后的光标位置
mov ax,Lastpos
sub ax,dx
dec ax
jz m100 ;[,]之后没有字符
inc di ;退回[,]之后
mov startpos,di ;此为字符串起点
dec bp ;若数字符后只有B或D或H,则BP=1,2或3,减1后0则不符
js m100 ;没有D或B 100 010 001 011 减后 011 001 000
cmp bp,2 ;2 ?
jb m64 ;0,1都ok
jz m100 ;=2, d和b并存又没有h
mov bp,2 ;置值
m64: ; bp=0 (b)or 1(d) or 2(h)
shl bp,1 ;根据BP(0或2)跳至2进位转16进位或10进位转16进位的子程序
call word ptr cs:HexprocTable[bp]
jc m100 ;错误,回存光标,离开
;以下输出到键盘缓冲
mov dx,Lastpos ;回到按F10时的光标位置
call SetCurPos ;设
mov bp,Lastpos ;最后位置
sub bp,firstpos ;减[,]后位置
;mov SendCount,bp ;退位(backspace)数
;----送至my key buffer起--
mov di,offset SendBuffer ;指向键盘缓冲(准备送出)
mov cx,bp ;退位(backspace)数
mov ah,0eh ;backspace 扫瞄码
mov al,08h ;backspace ASCII码
rep stosw ;送出cx个
mov si,offset OverwriteStr ;16进制的字符串
mov bx,di ;backspace扫瞄码之后
m65:
lodsb ;读入
or al,al ;是否0
jz m68 ;是,走
mov di,offset hexTable ;16进表格
mov cx,16 ;0-F
repnz scasb ;找按键
sub di,offset hexTable +1 ;哪一个
shl di,1
mov ax,word ptr ScanTable[di] ;根据16位字节,取scancode和ascii
mov [bx],ax ;存
add bx,2 ;下一个
;inc SendCount ;累加个数
jmp short m65 ;下一个
;----送至my key buffer完--
m68: mov sendFlag,1 ;启动送key标志
mov ax,offset SendBuffer
mov LastSendAddr,ax ;初始化最后地址
;call Sendkey ;离开,int9不做送key,由int1ch做
m90: popa
pop es
pop ds
ret
m100: mov dx,Lastpos ;不符要求,回存光标位置,离开
call SetCurPos
jmp short m90
;------------------------------------------------------------------------------
; 送出键值到键盘缓冲,每次15个,未完下次再送,直到完送.
Sendkey:push ds
push es
pusha
mov ax,cs
mov ds,ax
xor ax,ax
mov es,ax
mov si,041Ah ;键盘缓冲区开头位址
mov ax,es:[si] ;041A,键盘缓冲区开头位址
cmp ax,es:[si+2] ;041C,键盘缓冲区结束位址
jnz send90 ;不相同,即缓冲区仍有键值未清,走
mov si,LastSendAddr
mov di,15 ;一次送15key
send10:
mov cx,[si]
jcxz send20 ;送完了,走
mov ah,5 ;送出按键
int 16h
add si,2 ;下一个
dec di ;15完了?
jnz send10 ;未
mov LastSendAddr,si ;送完15键,但全数未完,保存最后key地址,下次用
jmp short send90 ;送完15key,走
send20: ;送完全部按键
mov sendflag,0 ;清除
send90: popa
pop es
pop ds
ret
;------------------------------------------------------------------------------
HtoD: call FindNonSpace
jz HtoDx ;找不到空白之外的字符
;si = first byte
call htoh ;dx:ax返回hex值
jc HtoDx ;错误,走
mov word ptr userinput,ax
mov word ptr userinput+2,dx
mov di,offset OverwriteStr
call print_dec ;out dx:ax(dec) to es:di
mov al,'D'
stosb
mov al,0
stosb
clc
ret
HtoDx: stc
ret
;------------------------------------------------------------------------------
;output DX:AX,dword (0-FFFFFFFFh / 0-4294967295) ;印出32BIT数值子程序
print_dec:
xor cx,cx
xchg bp,dx
mov si,10 ;div by 10
mov bx,30h
print_dec1:
or bp,bp
jz print_dec3
xchg bp,ax
xor dx,dx
div si
xchg bp,ax
div si
or dl,bl
push dx
inc cx
jmp short print_dec1
print_dec3:
xor dx,dx
div si
or dl,bl
push dx
inc cx
or ax,ax
jnz print_dec3
print_dec4:
pop ax
stosb
loop print_dec4
ret
;------------------------------------------------------------------------------
;转值子程序,把输入的10进制文字转成16进制
;输入:ds:si数字字符串起点,以0dh结束
;输出:ax=转换后的16进制值,cf=1表示有非数字字符
.386
GetValue:
push ebx
push edi
xor ebx,ebx
mov edi,10
GetV10: lodsb ;指向起点
and eax,000000ffh ;清除高bit,保留AL
cmp al,0 ;-----zero
jz Getvx
sub al,'0'
cmp al,9
ja Getvy
xchg ebx,eax ;交换
mul edi
or edx,edx
jnz Getvy
add ebx,eax ;累加
jc Getvy
jmp short GetV10
Getvx: mov eax,ebx ;ascii转值后由ax转回
clc ;成功cf=0
jmp short Getvz
Getvy: stc ;错误 cf=1
Getvz: pop edi
pop ebx
ret
;-------------------------------------------------------------------
;input : offset of last string in si
;output : value in hi-lo buffer
htoh: push cx
push di
xor edx,edx
hh10: lodsb
or al,al
jz hh80
mov ah,al
and ah,05fh ;转大写
cmp ah,'A' ;排除A-Z
jb hh20
cmp ah,'Z'
ja hh20
mov al,ah ;大写
hh20: lea di,hex_table[2] ;address of ascii_table
mov ecx,16 ;no.
repne scasb
jnz hh90 ;not found 0-F
sub di,(offset hex_table[2])+1 ;adjust position
mov cx,4
hh30: shr di,1 ;shift right side to carry
rcl edx,1 ;shift carry to right side
jc hh90 ;overflow
loop hh30
jmp short hh10
hh80: mov eax,edx
shr edx,16
clc
hh88: pop di
pop cx
ret
hh90: stc
jmp short hh88
;------------------------------------------------------------------------------
FindNonSpace:
mov di,startpos
cld
mov al,20h
mov cx,82
repe scasb
lea si,[di-1] ;si=di-1
mov cx,82
mov edx,0
ret
[此贴子已经被作者于2016-7-17 07:34编辑过]