]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/DEBUG/DEBCOM3.ASM
2 TITLE DEBCOM3
.ASM
- PART3 DEBUGGER COMMANDS
3 ; ROUTINES TO PERFORM DEBUGGER COMMANDS
6 %
OUT COMPONENT
=DEBUG
, MODULE
=DEBCOM3
15 CODE SEGMENT PUBLIC BYTE
18 CONST
SEGMENT PUBLIC BYTE
19 EXTRN USER_PROC_PDB
:WORD,RSTACK
:WORD,STACK:BYTE
20 EXTRN DSSAVE
:WORD,CSSAVE
:WORD,IPSAVE
:WORD,axSAVE
:WORD,dxSAVE
:WORD
21 EXTRN SSSAVE
:WORD,SPSAVE
:WORD,FLSAVE
:WORD
22 EXTRN NEXTCS
:WORD,NEXTIP
:WORD, RSETFLAG
:BYTE
28 DATA SEGMENT PUBLIC BYTE
29 EXTRN BRKCNT
:WORD,TCOUNT
:WORD,SWITCHAR
:BYTE,BPTAB
:BYTE
30 EXTRN BP_ERROR
:BYTE,COMP_ARG1
:WORD,COMP_ARG2
:WORD,COMP_ARG3
:WORD
31 EXTRN COMP_ARG4
:WORD,COMP_ARG5
:WORD,COMP_ARG6
:WORD,COMP_PTR
:BYTE
32 EXTRN ARG_BUF
:BYTE,ARG_BUF_PTR
:BYTE
33 EXTRN FZTRACE
:BYTE, SYNERR_PTR
:BYTE
41 DG GROUP
CODE,CONST
,CSTACK
,DATA
43 CODE SEGMENT PUBLIC BYTE
44 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
45 PUBLIC COMPARE
,INPUT
,OUTPUT
,GO
46 PUBLIC TRACE
,ZTRACE
,SKIP_FILE
47 EXTRN GETHEX
:NEAR,GETEOL
:NEAR,CRLF
:NEAR,ERR:NEAR, PERR
:NEAR
48 EXTRN HEX
:NEAR,DIGIT
:NEAR,SCANP
:NEAR,DISPREG
:NEAR
49 EXTRN COMMAND
:NEAR,DABORT
:NEAR,DELIM1
:NEAR,DELIM2
:NEAR
50 EXTRN NMIINT
:NEAR,NMIINTEND
:NEAR,PRINTF_CRLF
:NEAR
51 EXTRN ADDRESS
:NEAR,HEXIN
:NEAR,DSRANGE
:NEAR
52 ; just like trace except skips OVER next INT or CALL.
72 MOV ES,[CSSAVE
] ; point to instruction to execute
73 MOV DI,[IPSAVE
] ; include offset in segment
74 XOR DX,DX ; where to place breakpoint
76 MOV AL,ES:[DI] ; get the opcode
88 ; inc dx ; this seemed to put us in an endless
89 inc di ; loop, try this.
92 CMP AL,11101000B ; direct intra call
93 JZ ZTRACE3
; yes, 3 bytes
94 CMP AL,10011010B ; direct inter call
95 JZ ZTRACE5
; yes, 5 bytes
96 CMP AL,11111111B ; indirect?
97 JZ ZTRACEMODRM
; yes, go figure length
98 CMP AL,11001100B ; short interrupt?
99 JZ ZTRACE1
; yes, 1 byte
100 CMP AL,11001101B ; long interrupt?
101 JZ ZTRACE2
; yes, 2 bytes
102 CMP AL,11100010B ; loop
104 CMP AL,11100001B ; loopz/loope
106 CMP AL,11100000B ; loopnz/loopne
108 AND AL,11111110B ; check for rep
109 CMP AL,11110010B ; perhaps?
111 JMP STEP
; can't do anything special, step
113 MOV AL,ES:[DI+1] ; next instruction
114 AND AL,11111110B ; ignore w bit
115 CMP AL,10100100B ; MOVS
116 JZ ZTRACE2
; two byte
117 CMP AL,10100110B ; CMPS
118 JZ ZTRACE2
; two byte
119 CMP AL,10101110B ; SCAS
120 JZ ZTRACE2
; two byte
121 CMP AL,10101100B ; LODS
122 JZ ZTRACE2
; two byte
123 CMP AL,10101010B ; STOS
124 JZ ZTRACE2
; two byte
125 JMP STEP
; bogus, do single step
128 MOV AL,ES:[DI+1] ; get next byte
129 AND AL,11111000B ; get mod and type
130 CMP AL,01010000B ; indirect intra 8 bit offset?
131 JZ ZTRACE3
; yes, three byte whammy
132 CMP AL,01011000B ; indirect inter 8 bit offset
133 JZ ZTRACE3
; yes, three byte guy
134 CMP AL,10010000B ; indirect intra 16 bit offset?
135 JZ ZTRACE4
; four byte offset
136 CMP AL,10011000B ; indirect inter 16 bit offset?
137 JZ ZTRACE4
; four bytes
138 CMP AL,11010000B ; indirect through reg?
139 JZ ZTRACE2
; two byte instruction
140 JMP STEP
; can't figger out what this is!
151 ADD DI,DX ; offset to breakpoint instruction
152 MOV WORD PTR [BPTAB
],DI ; save offset
153 MOV WORD PTR [BPTAB
+2],ES ; save segment
154 MOV AL,ES:[DI] ; get next opcode byte
155 MOV BYTE PTR [BPTAB
+4],AL ; save it
156 MOV BYTE PTR ES:[DI],0CCH ; break point it
157 MOV [BRKCNT
],1 ; only this breakpoint
158 JMP DEXIT
; start the operation!
160 ; Trace 1 instruction or the number of instruction specified
161 ; by the parameter using 8086 trace mode. Registers are all
162 ; set according to values in save area
182 ; The 286 has a problem with trace mode and software interrupt instructions;
183 ; it treats them as atomic operations. We simulate the operation in software.
184 MOV ES,[CSSAVE
] ; Get next instruction pointer
186 MOV AL,ES:[DI] ; get next opcode
187 cmp al,0e4h ; check for 'IN' opcode
189 cmp es:byte ptr[di+1],21h
195 cmp al,0ech ; in al,DX ?
207 CMP AL,0CDH ; trace over an interrupt?
208 JZ DOINT
; no, check for other special cases
209 CMP AL,0CEH ; how about int overflow
211 TEST FLSAVE
,F_OVERFLOW
; see it overflow is present
213 MOV BX,4 ; INTO = INT 4
214 DEC IPSAVE
; INTO is a singel byte
219 MOV BX,3 ; INT 3 = CC
223 ; We have a software interrupt. Get destination vector
224 MOV BL,BYTE PTR ES:[DI+1] ; get vector number
225 XOR BH,BH ; clear out upper
227 SHL BX,1 ; word index
228 SHL BX,1 ; dword index
229 XOR DI,DI ; interrupt table
231 MOV AX,ES:[BX] ; point to vector
232 MOV BX,ES:[BX+2] ; point to vector
233 ; AX:BX is the vector. Swap it with currect CS:IP
234 XCHG AX,IPSAVE
; new CS:IP
236 ; AX:BX is old CS:IP. We 'PUSH' flags, oldCS and oldIP, reset flags (ifl) and
237 ; set CS:IP to point to interrupt instruction.
238 MOV ES,SSSAVE
; point to user stack
240 ; Take old flags and PUSH the flags.
241 MOV CX,FLSAVE
; get flags
243 MOV ES:[DI],CX ; rest of push
246 MOV ES:[DI],BX ; rest of push
249 ADD AX,2 ; increment IP
250 MOV ES:[DI],AX ; rest of push
252 MOV SPSAVE
,DI ; store
253 ; Take flags and turn interrupts off and trace mode off
254 AND CX,NOT F_INTERRUPT
; CLI
255 AND CX,NOT F_TRACE
; no trace
256 MOV FLSAVE
,CX ; rest of CLI
257 ; Set up correct process and go to normal reentry code.
259 MOV BX,[USER_PROC_PDB
]
260 MOV AH,SET_CURRENT_PDB
264 ; We need to special case the following instructions that may push a TRACE bit
265 ; on the stack: PUSHF (9C)
267 ; Save the opcode in A Special place
269 MOV RSETFLAG
,AL ; no bits to turn off
271 OR FLSAVE
,F_TRACE
; Turn on trace bit
274 IN AL,MASK_PORT
; Get current mask
277 MOV [OLD_MASK
],AL ; Save it
278 MOV AL,INT_MASK
; New mask
279 OUT MASK_PORT
,AL ; Set it
284 MOV BX,[USER_PROC_PDB
]
285 MOV AH,SET_CURRENT_PDB
288 ; Unfortunately, any system call we issue will muck with the current extended
289 ; errors. Here we must restore the extended error state so that if the user
290 ; program gets it, we do not interfere.
291 MOV AX,(SERVERCALL
SHL 8) + 10
292 MOV DX,OFFSET DG
:SAVESTATE
297 MOV WORD PTR DS:[12],OFFSET DG
:BREAKFIX
; Set vector 3--breakpoint instruction
298 MOV WORD PTR DS:[14],CS
299 MOV WORD PTR DS:[4],OFFSET DG
:REENTER
; Set vector 1--Single step
300 MOV WORD PTR DS:[6],CS
303 MOV WORD PTR DS:[8
CH],OFFSET DG
:CONTC
; Set vector 23H (CTRL-C)
304 MOV WORD PTR DS:[8EH
],CS
307 MOV SP,OFFSET DG
:STACK
333 ; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for
334 ; continuing, so we must pop that off.
337 JMP SHORT REENTERREAL
339 ; Re-entry point from breakpoint. Need to decrement instruction
340 ; pointer so it points to location where breakpoint actually
345 DEC WORD PTR [BP].OLDIP
349 ; Re-entry point from trace mode or interrupt during execution. All registers
350 ; are saved so they can be displayed or modified.
351 INTERRUPT_FRAME
STRUC
361 ASSUME
CS:DG
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
362 ; ReEnter is the main entry point for breakpoint interrupts and for trace mode
363 ; interrupts. We treat both of these cases identically: save state, display
364 ; registers and go for another command. If we get NMI's, we skip them or if
365 ; it turns out that we are debugging ourselves, we skip them.
367 ; Due to bogosities in the 808x chip, Consider tracing over an interrupt and
368 ; then setting a breakpoint to where the interrupt returns. You get the INT 3
369 ; and then trace mode gets invoked! This is why we ignore interrupts within
373 MOV BP,SP ; get a frame to address from
376 ; CMP AX,[BP].OLDCS ; Did we interrupt ourselves?
377 ; JNZ GOREENTER ; no, go reenter
380 CMP AX,OFFSET DG
:NMIINT
; interrupt below NMI interrupt?
381 JB GOREENTER
; yes, go reenter
382 CMP [BP].OLDIP
,OFFSET DG
:NMIINTEND
383 JAE GOREENTER
; interrupt above NMI interrupt?
384 POP AX ; restore state
386 SUB SP,6 ; switch TRACE and NMI stack frames
388 MOV BP,SP ; set up frame
389 PUSH AX ; get temp variable
390 MOV AX,[BP].OLDERIP
; get NMI Vector
391 MOV [BP].OLDIP
,AX ; stuff in new NMI vector
392 MOV AX,[BP].OLDERCS
; get NMI Vector
393 MOV [BP].OLDCS
,AX ; stuff in new NMI vector
394 MOV AX,[BP].OLDERF
; get NMI Vector
395 AND AH,0FEH ; turn off Trace if present
396 MOV [BP].OLDF
,AX ; stuff in new NMI vector
398 MOV [BP].OLDERIP
,OFFSET DG
:REENTER
; offset of routine
399 MOV [BP].OLDERCS
,CS ; and CS
406 MOV AL,CS:[OLD_MASK
] ; Recover Old mask
407 OUT MASK_PORT
,AL ; Restore it
410 ; Determine, based on the previous instruction, what we are supposed to do
411 ; to flags on the users stack.
414 ; OlderIP = flags. Turn off trace bit
415 AND [BP].OLDERIP
,NOT F_TRACE
420 MOV CS:[SPSAVE
+SEGDIF
],SP
421 MOV CS:[SSSAVE
+SEGDIF
],SS
424 MOV SP,OFFSET DG
:RSTACK
449 AND AX,NOT F_TRACE
; TURN OFf trace mode bit
461 MOV SP,OFFSET DG
:STACK
468 MOV WORD PTR DS:[8
CH],OFFSET DG
:DABORT
; Set Ctrl-C vector
469 MOV WORD PTR DS:[8EH
],CS
476 ; Since we are about to issue system calls, let's grab the current user's
477 ; extended error info.
478 MOV AH,GETEXTENDEDERROR
480 ASSUME
DS:NOTHING
,ES:NOTHING
482 MOV SAVESTATE
.DPL_AX
,AX
483 MOV SAVESTATE
.DPL_BX
,BX
484 MOV SAVESTATE
.DPL_CX
,CX
485 MOV SAVESTATE
.DPL_DX
,DX
486 MOV SAVESTATE
.DPL_SI
,SI
487 MOV SAVESTATE
.DPL_DI
,DI
488 MOV SAVESTATE
.DPL_DS
,DS
489 MOV SAVESTATE
.DPL_ES
,ES
496 MOV AH,GET_CURRENT_PDB
498 MOV [USER_PROC_PDB
],BX
500 MOV AH,SET_CURRENT_PDB
503 MOV SI,OFFSET DG
:BPTAB
508 LES DI,DWORD PTR [SI]
522 ; Input from the specified port and display result
524 MOV CX,4 ; Port may have 4 digits
525 CALL GETHEX
; Get port number in DX
528 IN AL,DX ; Variable port input
532 MOV DI,OFFSET DG
:ARG_BUF
533 CALL HEX
; And display
537 MOV DX,OFFSET DG
:ARG_BUF_PTR
540 ; Output a value to specified port.
542 MOV CX,4 ; Port may have 4 digits
543 CALL GETHEX
; Get port number
544 PUSH DX ; Save while we get data
545 MOV CX,2 ; Byte output only
546 CALL GETHEX
; Get data to output
548 XCHG AX,DX ; Output data in AL
551 OUT DX,AL ; Variable port output
556 MOV DX,CSSAVE
; set up start addresses
562 CMP BYTE PTR [SI],"="
570 ; Jump to program, setting up registers according to the
571 ; save area. up to 10 breakpoint addresses may be specified.
576 MOV DI,OFFSET DG
:BPTAB
582 PUSH BX ;AN000; DMS;SAVE BX - ADDRESS KILLS IT
584 POP BX ;AN000; DMS;RESTORE BX
586 MOV [DI],DX ; Save offset
587 MOV [DI+2],AX ; Save segment
588 ADD DI,5 ; Leave a little room
592 MOV DX,OFFSET DG
:BP_ERROR
; BP ERROR
598 MOV DI,OFFSET DG
:BPTAB
601 LDS SI,ES:DWORD PTR [DI]
604 MOV BYTE PTR [SI-1],0CCH
618 MOV CS:[SWITCHAR
],DL ; GET THE CURRENT SWITCH CHARACTER
634 CALL ADDRESS
; Same segment
642 CALL COMP
; Do one less than total
643 INC CX ; CX=1 (do last one)
647 ; Compare error. Print address, value; value, address.
663 MOV DX,OFFSET DG
:COMP_PTR
669 PROCEDURE CHECKNONE
,NEAR
672 MOV DX,OFFSET DG
:SYNERR_PTR
; ERROR MESSAGE