regs.asm
来自「比dos下的debug更好的debug程序源码」· 汇编 代码 · 共 396 行
ASM
396 行
;
; GRDP
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; Regs.asm
;
; Function: Handle register display and input
;
;MASM MODE
.model small
.386
include eprints.inc
include emtrap.inc
include einput.inc
include edis.inc
include eoptions.inc
include ehistory.inc
PUBLIC DisplayRegisters, ModifyRegisters, ReadReg
.code
;
; This is a list corresponding ASCII names for general purpose regs
; with the address the value can be found at;
;
peax dw offset RegdumpEAX
db 13,10,"eax:",0
pebx dw offset RegdumpEBX
db "ebx:",0
pecx dw offset RegdumpECX
db "ecx:",0
pedx dw offset RegdumpEDX
db "edx:",0
pesi dw offset RegdumpESI
db "esi:",0
pedi dw offset RegdumpEDI
db "edi:",0
pebp dw offset RegdumpEBP
db 13,10,"ebp:",0
pesp dw offset RegdumpESP
db "esp:",0
peip dw offset RegdumpEIP
db "eip:",0
dw 0
;
; a list of 8-bit register names
;
pal dw offset RegdumpEAX
db 13,10,"al:",0
dw offset RegdumpEAX+1
db "ah:",0
dw offset RegdumpEBX
db "bl:",0
dw offset RegdumpEBX+1
db "bh:",0
dw offset RegdumpECX
db "cl:",0
dw offset RegdumpECX+1
db "ch:",0
dw offset RegdumpEDX
db 13,10,"dl:",0
dw offset RegdumpEDX+1
db "dh:",0
dw 0
;
; a list of 16-bit register names
;
pax dw offset RegdumpEAX
db 13,10,"ax:",0
dw offset RegdumpEBX
db "bx:",0
dw offset RegdumpECX
db "cx:",0
dw offset RegdumpEDX
db "dx:",0
dw offset RegdumpESI
db "si:",0
dw offset RegdumpEDI
db "di:",0
dw offset RegdumpEBP
db 13,10,"bp:",0
dw offset RegdumpESP
db "sp:",0
dw offset RegdumpEIP
db "ip:",0
pds dw offset RegdumpDS
db 13,10,"ds: ",0
PES dw offset RegdumpES
db "es:",0
pfs dw offset RegdumpFS
db "fs:",0
pgs dw offset RegdumpGS
db "gs:",0
Pss dw offset RegdumpSS
db "ss:",0
pcs dw offset RegdumpCS
db "cs:",0
dw 0
peflags dw offset RegdumpFLAGS
db "eflags:",0
dw 0
flm label byte
db 11
dd "NVOV"
db 10
dd "UPDN"
db 9
dd "DIEI"
db 7
dd "PLMI"
db 6
dd "NZZR"
db 4
dd "NAAC"
db 2
dd "POPE"
db 0
dd "NCCY"
db -1
db 0
;
; Print a general purpose reg and it's value
;
rPutDword PROC
test [optdword],0ffh
jz rPutWord
lods word ptr cs:[si]; Get pointer to val
mov bx,ax
mov eax,[bx] ; Get val
push eax ;
mov bx,si ; Get text pointer
call olMessage
pop eax ;
call printdword ; Print value
call printspace ;
ret
rPutDword ENDP
;
; Print a segment reg and its value
;
rPutWord PROC
lods word ptr cs:[si]; Get pointer to value
mov bx,ax
mov ax,[bx] ; Get value
push ax ;
mov bx,si ; Pointer to text
call olMessage
pop ax ;
call printword ; Print value
call printspace ;
ret
rPutWord ENDP
;
; Print either the GP regs or the SEG regs
; INPUT: DX has the address of the appropriate print routine
; SI points to text
; By implication, two consecutive bytes of 0 exit the routine, else we
; print each string until we reach that 00 00
;
PrintaFew PROC
call dx ; Call the print routine
pf_lp:
lods byte ptr cs:[si]; Wade past the text
or al,al ;
jnz pf_lp ;
test WORD PTR cs:[si],-1 ; See if trailer found
jnz PrintAFew ; Go print another
ret
PrintAFew ENDP
;
; try to find a match for a register spec
; INPUT: SI points at the input line where we might find a register by name
; DI points to an EAX structure consisting of a pointer to a bucket
; to put EAX into, followed by a display string of 'EAX'
; OUTPUT:SI is moved past the register if we found one, else same
; DI points to bucket to hold this register value if register found
;
skimreg PROC
push di ;save address of structure
push si ;save address of input
xchg si,di ;di now input, si is structure
add si,2 ;go past EAX bucket pointer to str
srlp:
cmp byte ptr cs:[si],' ' ;anything below a space
jnc oktry ;is OK, so skip 0D, 0A at EAX
inc si ;goto next character
jmp srlp ;until letter is found
oktry:
cmp byte ptr cs:[si],':' ;colon follows all register names
jz match ;so if all alike, we found our reg
cmps byte ptr cs:[si],es:[di] ;else do a character match
jz oktry ;if a match, keep going to colon
pop di ;else pop address of input to di
add sp,2 ;clear struct address off stack
srlp2:
lods byte ptr cs:[si] ;find terminating 0, following colon
or al,al ;is this it?
jnz srlp2 ;keep looking until found
test word ptr cs:[si],0ffffh ;table ends with word of 0
xchg si,di ;get our regs straightened out
jnz skimreg ;and examine next struct
sub al,al ;no find, so
inc al ;return no carry
ret
match:
add sp,2 ;clear input address off stack
sub eax,eax ;clear out EAX
xchg si,di ;SI now input past found register
pop di ;di points to top struct
mov di,cs:[di] ;point to his bucket
stc ;indicate register found
ret
skimreg ENDP
;
; search all the name tables for a match
; INPUT: SI points at the input line where we expect to find a register
; OUTPUT: ZR if found a non-segment register, NZ if we didn't
; CY if the request was NOT for a segment register, NC if it was
; SI moved past the register on the input line
;
FindRegister PROC
mov di,offset cs:peax ;find pointer to EAX bucket
call skimreg ;look for register string match
mov cl,4 ;used for dword length
jc frnoseg ;carry means we found dword reg
mov di,offset cs:pal ;else look for byte reg
call skimreg ;save technique
mov cl,1 ;set byte length
jc frnoseg ;in case we found it
mov di,offset cs:peflags ;else maybe user doing flags?
call skimreg ;try 'eflags'
mov cl,4 ;say 4 bytes for this
jc frnoseg ;if found
mov bl,[si+1] ;else bl=2d char in input string
mov di,offset cs:pax ;look for word regs
call skimreg ;in the table
mov cl,2 ;assume word
jnc frnotfound ;if not found, bl is ???
cmp bl,'s' ;might it be a segment reg?
stc ;assume not???
jnz frnoseg ;jmp if not
clc ;else clear carry
frnoseg:
mov al,0ffH ;set ZF without affecting carry flag
inc al
ret ;and return success
frnotfound:
sub ax,ax ;set NZ
inc ax
stc ;and the carry
ret
FindRegister ENDP
;
; read the value of a reg (used by input routines)
; INPUT: SI points at the input line
; OUTPUT:If we found a byte or word register, EAX holds the zero-extended
; value that was in the corresponding bucket.
; If we found a dword register, EAX holds the dword value
; NZ if register not found by name, but still might be a number
; Else, NC if segment reg, CY if non-segment reg found
; SI moved past a register found by name, else not moved
;
ReadReg PROC
push ecx ;ECX holds ???
call FindRegister ;see if we found a non-segment reg
jnz notreg ;if not, jmp
pushf ;save flags (carry?)
mov eax,[di] ;get value from bucket
cmp cl,4 ;was it a dword?
jz rr_exit ;if so, exit
movzx eax,ax ;else zero extend into EAX
cmp cl,2 ;was it a word register
jz rr_exit ;if so, we have it
movzx eax,al ;else zero extend EAX
rr_exit:
popf ;restore flags
notreg:
pop ecx ;and ECX
ret
ReadReg ENDP
;
; Read value for a register back into memory (R) command
;
ReadRegValue PROC
call WadeSpace
jz doregprompt
inc si
cmp al,':'
jz ReadRegValue
cmp al,'='
jz ReadRegValue
dec si
call ReadNumber
ret
doregprompt:
push bx ; Else put up prompt
push cx ;
PRINT_MESSAGE <13,10,": ">
call histoff
call GetInputLine ; Get input line
call histon
pop cx ;
pop bx ;
call WadeSpace ; Ignore spaces
jz short rr_out ; Quit if so
call ReadNumber
ret
rr_out:
stc
ret
ReadRegValue ENDP
;
; main 'Reg' command
;
ModifyRegisters PROC
call wadespace ; Wade through spaces
jz DisplayRegisters ; Display regs
call FindRegister
jnz badreg
push di
call ReadRegValue
pop di
jc badreg2
cmp cl,4
jnz wordreg
mov [di],eax
clc
ret
wordreg:
cmp cl,2
jnz bytereg
mov [di],ax
badreg2:
clc
ret
badreg:
stc
ret
bytereg:
mov [di],al
ret
ModifyRegisters ENDP
putflags PROC
mov si,offset cs:flm
putflags2:
lods byte ptr cs:[si]
or al,al
js pfdone
movzx ax,al
bt word ptr [RegdumpFLAGS],ax
lods dword ptr cs:[si]
mov edx,eax
jc isclr
shr edx,16
isclr:
xchg dh,dl
call PutChar
xchg dl,dh
call PutChar
call PrintSpace
jmp putflags2
pfdone:
ret
putflags ENDP
;
; Display the processor regs
;
DisplayRegisters PROC
mov word ptr [RegdumpEIP+2],0 ;clear high word of EIP
pushfd ;move eflags
pop eax ;to EAX
shr eax,16 ;get upper 16 flagbits
mov word ptr [RegdumpFLAGS+2],ax ;save in high flag bucket
mov si, offset cs:peax ; Print GP regs
mov dx,offset cs:rPutDword ; with the DWORD function
call PrintAFew ; Print them
mov si,offset cs:peflags ;Put the flags
call rPutDword
call putflags
mov si,offset cs:pds ; Now put the segs
mov dx,offset cs:rPutWord
call PrintAFew
mov bx,word ptr [RegdumpEIP] ; Dissassemble at current code pointer
mov dx,[RegdumpCS]
call DisOneLine
clc
ret
DisplayRegisters ENDP
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?