1 | ;
|
---|
2 | ; DEBUG.ASM -- Built-in debugger
|
---|
3 | ;
|
---|
4 | ; Copyright (c) 1991-1996 by Eberhard Mattes
|
---|
5 | ;
|
---|
6 | ; This file is part of emx.
|
---|
7 | ;
|
---|
8 | ; emx is free software; you can redistribute it and/or modify it
|
---|
9 | ; under the terms of the GNU General Public License as published by
|
---|
10 | ; the Free Software Foundation; either version 2, or (at your option)
|
---|
11 | ; any later version.
|
---|
12 | ;
|
---|
13 | ; emx is distributed in the hope that it will be useful,
|
---|
14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | ; GNU General Public License for more details.
|
---|
17 | ;
|
---|
18 | ; You should have received a copy of the GNU General Public License
|
---|
19 | ; along with emx; see the file COPYING. If not, write to
|
---|
20 | ; the Free Software Foundation, 59 Temple Place - Suite 330,
|
---|
21 | ; Boston, MA 02111-1307, USA.
|
---|
22 | ;
|
---|
23 | ; See emx.asm for a special exception.
|
---|
24 | ;
|
---|
25 |
|
---|
26 | INCLUDE EMX.INC
|
---|
27 | INCLUDE EXCEPT.INC
|
---|
28 | INCLUDE OPRINT.INC
|
---|
29 | INCLUDE DISASM.INC
|
---|
30 | INCLUDE SEGMENTS.INC
|
---|
31 | INCLUDE SYMBOLS.INC
|
---|
32 | INCLUDE SIGNAL.INC
|
---|
33 | INCLUDE PROCESS.INC
|
---|
34 | INCLUDE PAGING.INC
|
---|
35 | INCLUDE PMINT.INC
|
---|
36 | INCLUDE TABLES.INC
|
---|
37 | INCLUDE PMIO.INC
|
---|
38 | INCLUDE SWAPPER.INC
|
---|
39 | INCLUDE FILEIO.INC
|
---|
40 | INCLUDE UTILS.INC
|
---|
41 |
|
---|
42 | PUBLIC STEP_FLAG, DEBUG_AVAIL, DEBUG_SER_FLAG, DEBUG_SER_PORT
|
---|
43 | PUBLIC DEBUG_EXCEPTION, SET_BREAKPOINT, INS_BREAKPOINTS
|
---|
44 | PUBLIC DEBUG_RESUME, DEBUG_STEP, DEBUG_QUIT, DEBUG_INIT
|
---|
45 |
|
---|
46 | BP_INACTIVE = 0 ; Entry unused
|
---|
47 | BP_BREAKPOINT = 1 ; Code breakpoint
|
---|
48 | BP_WATCHPOINT_R = 2 ; R/W watchpoint
|
---|
49 | BP_WATCHPOINT_W = 3 ; W watchpoint
|
---|
50 | BP_WATCHPOINT_X = 4 ; X watchpoint
|
---|
51 |
|
---|
52 | BREAKPOINT STRUCT
|
---|
53 | BP_TYPE DB ? ; Breakpoint type (see above)
|
---|
54 | BP_LEN DB ? ; Watchpoint length
|
---|
55 | BP_SEL DW ? ; Selector
|
---|
56 | BP_OFF DD ? ; Offset
|
---|
57 | BP_ADDR DD ? ; Linear address
|
---|
58 | BP_VAL DD ? ; Watchpoint: initial value
|
---|
59 | BREAKPOINT ENDS
|
---|
60 |
|
---|
61 | SV_DATA SEGMENT
|
---|
62 |
|
---|
63 | DEBUG_SER_PORT DW 02F8H ; COM2
|
---|
64 | DEBUG_SER_FLAG DB FALSE
|
---|
65 |
|
---|
66 | STEP_FLAG DB FALSE
|
---|
67 | DEBUG_AVAIL DB NOT FALSE
|
---|
68 |
|
---|
69 | DEBUG_SHOW_PC DB NOT FALSE
|
---|
70 | DEBUG_STOP DB NOT FALSE
|
---|
71 | GO_FLAG DB FALSE
|
---|
72 | DEBUG_COUNT DB 0
|
---|
73 | FATAL DB ?
|
---|
74 | DA_SYM_FLAG DB ?
|
---|
75 | DA_EMPTY_FLAG DB ?
|
---|
76 | NEXT_CS DW ?
|
---|
77 | NEXT_EIP DD ?
|
---|
78 |
|
---|
79 | B_NEXT DB 0
|
---|
80 | B_COLUMN DB 0
|
---|
81 |
|
---|
82 | TALIGN 2
|
---|
83 | BREAKPOINTS BREAKPOINT 4 DUP (<BP_INACTIVE>)
|
---|
84 |
|
---|
85 | TALIGN 2
|
---|
86 | GCHAR DW B_CHAR
|
---|
87 | GTEXT DW B_TEXT
|
---|
88 | GDWORD DW B_DWORD
|
---|
89 | GWORD DW B_WORD
|
---|
90 | GBYTE DW B_BYTE
|
---|
91 | GCRLF DW B_CRLF
|
---|
92 | GINCHAR DW B_INCHAR
|
---|
93 | DA_SYM_ADDR DD ?
|
---|
94 | RANGE_SEL DW ?
|
---|
95 | RANGE_OFF DD ?
|
---|
96 | ADDR_LIN DD ?
|
---|
97 | ADDR_ARG DD ?
|
---|
98 | SEARCH_SEL DW ?
|
---|
99 | SEARCH_OFF DD ?
|
---|
100 | SEARCH_LEN DD ?
|
---|
101 | SEARCH_SIZE DD ?
|
---|
102 | ADDR_SEL DW ?
|
---|
103 | ADDR_OFF DD ?
|
---|
104 | ADDR_COUNT DD ?
|
---|
105 | SEL_SEL DW ?
|
---|
106 | SEL_COUNT DW ?
|
---|
107 | U_LAST_SEL DW 0
|
---|
108 | U_LAST_OFF DD ?
|
---|
109 | D_LAST_SEL DW 0
|
---|
110 | D_LAST_OFF DD ?
|
---|
111 | WP_LEN DB ?
|
---|
112 | WP_TYPE DB ?
|
---|
113 | SKIP_FLAG DB FALSE
|
---|
114 | WATCH_FAILURES DB ?
|
---|
115 | XOFF DB FALSE
|
---|
116 | LOOK_AHEAD DB 0
|
---|
117 | LIST_ALL DB FALSE
|
---|
118 |
|
---|
119 | SEARCH_BUF DB 64 DUP (?)
|
---|
120 |
|
---|
121 | FLAG_TAB DW 0001H
|
---|
122 | DB "NCCY"
|
---|
123 | DW 0004H
|
---|
124 | DB "PEPO"
|
---|
125 | DW 0010H
|
---|
126 | DB "NAAC"
|
---|
127 | DW 0040H
|
---|
128 | DB "NZZR"
|
---|
129 | DW 0080H
|
---|
130 | DB "PLNG"
|
---|
131 | DW 0200H
|
---|
132 | DB "DIEI"
|
---|
133 | DW 0400H
|
---|
134 | DB "UPDN"
|
---|
135 | DW 0800H
|
---|
136 | DB "NVOV"
|
---|
137 | DW 0000H
|
---|
138 |
|
---|
139 | R8 = 0
|
---|
140 | R16 = 1
|
---|
141 | R32 = 2
|
---|
142 |
|
---|
143 | REGISTER MACRO @NAME, @SIZE, @OFFSET
|
---|
144 | DB @NAME, @SIZE, @OFFSET
|
---|
145 | ENDM
|
---|
146 |
|
---|
147 | REG_TAB LABEL BYTE
|
---|
148 | REGISTER "EFLAGS", R32, 52
|
---|
149 | REGISTER "EAX", R32, 36
|
---|
150 | REGISTER "EBX", R32, 24
|
---|
151 | REGISTER "ECX", R32, 32
|
---|
152 | REGISTER "EDX", R32, 28
|
---|
153 | REGISTER "ESI", R32, 12
|
---|
154 | REGISTER "EDI", R32, 8
|
---|
155 | REGISTER "EBP", R32, 16
|
---|
156 | REGISTER "ESP", R32, 56 ; See GET_REG
|
---|
157 | REGISTER "EIP", R32, 44
|
---|
158 | REGISTER "AX", R16, 36
|
---|
159 | REGISTER "BX", R16, 24
|
---|
160 | REGISTER "CX", R16, 32
|
---|
161 | REGISTER "DX", R16, 28
|
---|
162 | REGISTER "SI", R16, 12
|
---|
163 | REGISTER "DI", R16, 8
|
---|
164 | REGISTER "BP", R16, 16
|
---|
165 | REGISTER "SP", R16, 56 ; See GET_REG
|
---|
166 | REGISTER "IP", R16, 44
|
---|
167 | REGISTER "AL", R8, 36
|
---|
168 | REGISTER "BL", R8, 24
|
---|
169 | REGISTER "CL", R8, 32
|
---|
170 | REGISTER "DL", R8, 28
|
---|
171 | REGISTER "AH", R8, 37
|
---|
172 | REGISTER "BH", R8, 25
|
---|
173 | REGISTER "CH", R8, 33
|
---|
174 | REGISTER "DH", R8, 29
|
---|
175 | REGISTER "CS", R16, 48
|
---|
176 | REGISTER "DS", R16, 6
|
---|
177 | REGISTER "ES", R16, 4
|
---|
178 | REGISTER "FS", R16, 2
|
---|
179 | REGISTER "GS", R16, 0
|
---|
180 | REGISTER "SS", R16, 60 ; See GET_REG
|
---|
181 | REGISTER 0FFH, 0FFH, 0FFH
|
---|
182 |
|
---|
183 | $EXCEPT DB "Exception ", 0
|
---|
184 | $CR2 DB " CR2=", 0
|
---|
185 | $ERRCD DB "ERRCD=", 0
|
---|
186 | $BREAKPOINT DB "Breakpoint ", 0
|
---|
187 | $WATCHPOINT DB "Watchpoint ", 0
|
---|
188 | $INPUT_ERROR DB "Input error", CR, LF, 0
|
---|
189 | $INVALID_SEL DB "Invalid selector", CR, LF, 0
|
---|
190 | $BEYOND_LIMIT DB "Offset beyond segment limit", CR, LF, 0
|
---|
191 | $ALIGNMENT DB "Address not correctly aligned", CR, LF, 0
|
---|
192 | $ADDR_FAILURE DB "GET_LIN failed", CR, LF, 0
|
---|
193 | $PAGE_DIR DB "Page table not present", CR, LF, 0
|
---|
194 | $PHYSICAL DB "physical=", 0
|
---|
195 | $LINEAR DB "linear=", 0
|
---|
196 | $EXTERNAL DB "external=", 0
|
---|
197 | $LINE DB " line ", 0
|
---|
198 | $RPL DB ": RPL=", 0
|
---|
199 | $TI_GDT DB " GDT ", 0
|
---|
200 | $TI_LDT DB " LDT ", 0
|
---|
201 | $SEL_INVALID DB "invalid selector", 0
|
---|
202 | $DPL DB " DPL=", 0
|
---|
203 | $DATA DB "data segment", 0
|
---|
204 | $CODE DB "code segment", 0
|
---|
205 | $BASE DB " base=", 0
|
---|
206 | $LIMIT DB " limit=", 0
|
---|
207 | $SEL_16 DB "16-bit ", 0
|
---|
208 | $SEL_32 DB "32-bit ", 0
|
---|
209 | $INT DB "int gate", 0
|
---|
210 | $TRAP DB "trap gate", 0
|
---|
211 | $TSS DB "TSS", 0
|
---|
212 | $CALL DB "call gate", 0
|
---|
213 | $TASK DB "task gate", 0
|
---|
214 | $LDT DB "LDT", 0
|
---|
215 | $NULL DB "null", 0
|
---|
216 |
|
---|
217 | $INSBRK DB "INS_BREAKPOINTS", CR, LF, 0
|
---|
218 | $CONTINUE DB "CONTINUE", CR, LF, 0
|
---|
219 | $DO_STEP DB "DO_STEP", CR, LF, 0
|
---|
220 | $DO_CALL DB "DO_CALL", CR, LF, 0
|
---|
221 | $DEBUG_EXCEPTION DB "DEBUG_EXCEPTION ", 0
|
---|
222 | $RUN DB "RUN", CR, LF, 0
|
---|
223 |
|
---|
224 | $EMPTY DB "empty", 0
|
---|
225 | $INFINITY DB "invalid or infinity", 0
|
---|
226 | $ZERO DB "zero", 0
|
---|
227 | $CW DB "CW=", 0
|
---|
228 | $SW DB " SW=", 0
|
---|
229 | $C3210 DB " C3210=", 0
|
---|
230 |
|
---|
231 | $SWAP_FAULTS DB CR, LF
|
---|
232 | DB "Swapper statistics: F=", 0
|
---|
233 | $SWAP_READS DB " R=", 0
|
---|
234 | $SWAP_WRITES DB " W=", 0
|
---|
235 | $SNATCH_COUNT DB " N=", 0
|
---|
236 | $SWAP_SIZE DB " S=", 0
|
---|
237 |
|
---|
238 | $INFO_TITLE DB "idx pid ppid file handles", CR, LF, 0
|
---|
239 | ; xx* xxxxxxxx xxxxxxxx xx
|
---|
240 |
|
---|
241 | INPUT_BUF LABEL BYTE
|
---|
242 | DISASM_BUF DB 80 DUP (?)
|
---|
243 | SYMBOL_BUF DB 80 DUP (?)
|
---|
244 |
|
---|
245 | SV_DATA ENDS
|
---|
246 |
|
---|
247 | SV_CODE SEGMENT
|
---|
248 |
|
---|
249 | .386P
|
---|
250 |
|
---|
251 | ASSUME CS:SV_CODE, DS:NOTHING
|
---|
252 |
|
---|
253 | ;
|
---|
254 | ; Set EFLAGS for resuming current process (without stepping)
|
---|
255 | ;
|
---|
256 | ; In: SS:BP Interrupt/exception stack frame
|
---|
257 | ;
|
---|
258 | ASSUME BP:PTR ISTACKFRAME
|
---|
259 | DEBUG_RESUME PROC NEAR
|
---|
260 | AND I_EFLAGS, NOT FLAG_TF
|
---|
261 | OR I_EFLAGS, FLAG_RF
|
---|
262 | RET
|
---|
263 | ASSUME BP:NOTHING
|
---|
264 | DEBUG_RESUME ENDP
|
---|
265 |
|
---|
266 |
|
---|
267 | ;
|
---|
268 | ; Set EFLAGS for single stepping current process
|
---|
269 | ;
|
---|
270 | ; In: SS:BP Interrupt/exception stack frame
|
---|
271 | ;
|
---|
272 | ASSUME BP:PTR ISTACKFRAME
|
---|
273 | DEBUG_STEP PROC NEAR
|
---|
274 | OR I_EFLAGS, FLAG_TF
|
---|
275 | RET
|
---|
276 | ASSUME BP:NOTHING
|
---|
277 | DEBUG_STEP ENDP
|
---|
278 |
|
---|
279 |
|
---|
280 | ;
|
---|
281 | ; Exception 1 (debug)
|
---|
282 | ;
|
---|
283 | ASSUME DS:SV_DATA
|
---|
284 | ASSUME BP:PTR ISTACKFRAME
|
---|
285 | TALIGN 2
|
---|
286 | DEBUG_EXCEPTION PROC NEAR
|
---|
287 | XOR EAX, EAX
|
---|
288 | MOV DR7, EAX ; Disable break points
|
---|
289 | MOV EBX, DR6 ; Copy DR6 to EBX
|
---|
290 | MOV DR6, EAX ; DR6 never cleared by 386
|
---|
291 | MOV ECX, CR2 ; Copy CR2 to ECX
|
---|
292 | STI
|
---|
293 | CMP DEBUG_FLAG, FALSE
|
---|
294 | JE SHORT DEX0
|
---|
295 | LEA EDX, $DEBUG_EXCEPTION
|
---|
296 | CALL GTEXT
|
---|
297 | MOV AX, I_CS
|
---|
298 | CALL GWORD
|
---|
299 | MOV AL, ":"
|
---|
300 | CALL GCHAR
|
---|
301 | MOV EAX, I_EIP
|
---|
302 | CALL GDWORD
|
---|
303 | CALL GCRLF
|
---|
304 | DEX0: MOV AL, EXCEPT_NO ; Get exception number
|
---|
305 | CMP AL, 1 ; Debugging exception?
|
---|
306 | JE SHORT REASON1 ; Yes -> check for reason
|
---|
307 | ;
|
---|
308 | ; Fatal exception or breakpoint instruction
|
---|
309 | ;
|
---|
310 | LEA EDX, $EXCEPT
|
---|
311 | CALL GTEXT
|
---|
312 | CALL GBYTE
|
---|
313 | MOV AL, ":"
|
---|
314 | CALL GCHAR
|
---|
315 | MOV AL, " "
|
---|
316 | CALL GCHAR
|
---|
317 | MOV AL, EXCEPT_NO
|
---|
318 | CALL EXCEPT_NAME
|
---|
319 | CALL GTEXT
|
---|
320 | CALL GCRLF
|
---|
321 | MOV FATAL, NOT FALSE
|
---|
322 | CMP EXCEPT_NO, 3 ; INT 3
|
---|
323 | JNE SHORT DEX1
|
---|
324 | MOV FATAL, FALSE
|
---|
325 | DEX1: CMP EXCEPT_NO, 8
|
---|
326 | JB SHORT DEX9
|
---|
327 | CMP EXCEPT_NO, 14
|
---|
328 | JA SHORT DEX9
|
---|
329 | LEA EDX, $ERRCD
|
---|
330 | CALL GTEXT
|
---|
331 | MOV EAX, I_ERRCD
|
---|
332 | CALL GDWORD
|
---|
333 | CMP EXCEPT_NO, 14 ; Page fault?
|
---|
334 | JNE SHORT DEX8
|
---|
335 | LEA EDX, $CR2
|
---|
336 | CALL GTEXT
|
---|
337 | MOV EAX, ECX
|
---|
338 | CALL GDWORD
|
---|
339 | DEX8: CALL GCRLF
|
---|
340 | DEX9: MOV AL, 1 ; New disassembly
|
---|
341 | JMP SHOW
|
---|
342 |
|
---|
343 | ;
|
---|
344 | ; Debugging exception
|
---|
345 | ;
|
---|
346 | REASON1: MOV FATAL, FALSE ; Not a fatal exception
|
---|
347 | ;
|
---|
348 | ; Check for X type watchpoints
|
---|
349 | ;
|
---|
350 | LEA SI, BREAKPOINTS
|
---|
351 | ASSUME SI:PTR BREAKPOINT
|
---|
352 | MOV CX, 4
|
---|
353 | MOV WATCH_FAILURES, 0
|
---|
354 | MOV EDX, 0001H ; B0
|
---|
355 | CHECK_WP: CMP [SI].BP_TYPE, BP_WATCHPOINT_X
|
---|
356 | JNE SHORT CHECK_WP9 ; Skip other entries
|
---|
357 | CALL WATCH_GET ; Read memory
|
---|
358 | CMP EAX, [SI].BP_VAL ; Changed?
|
---|
359 | JNE SHORT CHECK_WP1 ; Yes -> hit
|
---|
360 | INC WATCH_FAILURES ; Increment number of non-hits
|
---|
361 | JMP SHORT CHECK_WP9 ; Next entry
|
---|
362 | CHECK_WP1: OR EBX, EDX ; Set Bx bit of DR6
|
---|
363 | CHECK_WP9: SHL EDX, 1 ; Next Bx bit
|
---|
364 | ADD SI, SIZE BREAKPOINT
|
---|
365 | LOOP CHECK_WP
|
---|
366 | ASSUME SI:NOTHING
|
---|
367 | TEST EBX, 0FH ; Any breakpoints or wpx hits?
|
---|
368 | JNZ SHORT SHOW_BP ; Yes -> display breakpoints
|
---|
369 | CMP WATCH_FAILURES, 0 ; Any X watchpoint?
|
---|
370 | JNE SHORT WATCH1 ; Yes -> continue?
|
---|
371 | MOV AL, FALSE ; Continue disassembly
|
---|
372 | JMP SHOW ; Stop
|
---|
373 |
|
---|
374 | WATCH1: CMP GO_FLAG, FALSE ; GO command?
|
---|
375 | JE SHOW ; No -> stop
|
---|
376 | JMP CONTINUE ; Continue program
|
---|
377 | ;
|
---|
378 | ; Display breakpoints
|
---|
379 | ;
|
---|
380 | SHOW_BP: LEA SI, BREAKPOINTS
|
---|
381 | ASSUME SI:PTR BREAKPOINT
|
---|
382 | MOV CX, 4
|
---|
383 | SHOW_BP1: SHR EBX, 1 ; Test in turn B0, B1, B2, B3
|
---|
384 | JNC SHORT SHOW_BP9 ; Not set -> skip
|
---|
385 | CMP [SI].BP_TYPE, BP_INACTIVE ; B1 seems to be inaccurate
|
---|
386 | JE SHORT SHOW_BP9
|
---|
387 | LEA EDX, $BREAKPOINT ; Breakpoint
|
---|
388 | CMP [SI].BP_TYPE, BP_BREAKPOINT
|
---|
389 | JE SHORT SHOW_BP2
|
---|
390 | LEA EDX, $WATCHPOINT ; Watchpoint
|
---|
391 | SHOW_BP2: CALL GTEXT ; Display breakpoint type
|
---|
392 | MOV AL, "4"
|
---|
393 | SUB AL, CL
|
---|
394 | CALL GCHAR ; Display breakpoint number
|
---|
395 | CALL GCRLF
|
---|
396 | SHOW_BP9: ADD SI, SIZE BREAKPOINT ; Next breakpoint
|
---|
397 | LOOP SHOW_BP1
|
---|
398 | ASSUME SI:NOTHING
|
---|
399 | MOV AL, 1 ; New disassembly
|
---|
400 | ;
|
---|
401 | ; Show disassembled instruction
|
---|
402 | ;
|
---|
403 | SHOW: CMP DEBUG_SHOW_PC, FALSE ; Disassemble?
|
---|
404 | JE SHORT DEBUG_01 ; No -> skip
|
---|
405 | CALL TRACE_DISASM ; Show current instruction
|
---|
406 | DEBUG_01: CMP FATAL, FALSE ; Fatal exception?
|
---|
407 | JNE STOP1 ; Yes -> stop
|
---|
408 | CMP DEBUG_STOP, FALSE ; Non-stop mode?
|
---|
409 | JE DO_STEP ; Yes -> continue
|
---|
410 | CMP DEBUG_COUNT, 0 ; Multiple steps?
|
---|
411 | JE SHORT STOP1 ; No -> stop
|
---|
412 | DEC DEBUG_COUNT ; Another step?
|
---|
413 | JNZ DO_STEP ; Yes -> continue
|
---|
414 | ;
|
---|
415 | ; Stop program, wait for command
|
---|
416 | ;
|
---|
417 | STOP1: MOV DEBUG_COUNT, 0 ; Disable multiple steps
|
---|
418 | MOV DEBUG_STOP, NOT FALSE ; Disable non-stop mode
|
---|
419 | MOV DEBUG_SHOW_PC, NOT FALSE ; Enable disassembly
|
---|
420 | MOV BREAKPOINTS[0].BP_TYPE, BP_INACTIVE ; Delete bp 0
|
---|
421 | MOV GO_FLAG, FALSE ; No GO command active
|
---|
422 | ;
|
---|
423 | ; Wait for command
|
---|
424 | ;
|
---|
425 | KEY: CALL GINCHAR
|
---|
426 | OR AL, AL ; Extended key code?
|
---|
427 | JZ FKEY ; Yes ->
|
---|
428 | ;
|
---|
429 | ; Check for digits
|
---|
430 | ;
|
---|
431 | MOV AH, 10
|
---|
432 | CMP AL, "0" ; 10 steps?
|
---|
433 | JE CMD_MULT ; Yes ->
|
---|
434 | JB SHORT KEY1
|
---|
435 | MOV AH, AL
|
---|
436 | SUB AH, "0"
|
---|
437 | CMP AL, "9" ; Multiple steps (1-9) ?
|
---|
438 | JBE CMD_MULT ; Yes ->
|
---|
439 | ;
|
---|
440 | ; Check for other commands
|
---|
441 | ;
|
---|
442 | KEY1: CALL UPPER ; Convert to upper case
|
---|
443 | CMP AL, "." ; Registers
|
---|
444 | JE CMD_DOT
|
---|
445 | CMP AL, ":" ; Silent
|
---|
446 | JE CMD_SILENT
|
---|
447 | CMP AL, "A" ; Address
|
---|
448 | JE CMD_ADDR
|
---|
449 | CMP AL, "B" ; Breakpoint
|
---|
450 | JE CMD_BREAK
|
---|
451 | CMP AL, "C" ; Call
|
---|
452 | JE CMD_CALL
|
---|
453 | CMP AL, "D" ; Display
|
---|
454 | JE CMD_DISPLAY
|
---|
455 | CMP AL, "F" ; 387 status
|
---|
456 | JE CMD_387
|
---|
457 | CMP AL, "G" ; Go
|
---|
458 | JE CMD_GO
|
---|
459 | CMP AL, "I" ; Info
|
---|
460 | JE CMD_INFO
|
---|
461 | CMP AL, "K" ; Kill
|
---|
462 | JE CMD_KILL
|
---|
463 | CMP AL, "L" ; Selector
|
---|
464 | JE CMD_SELECTOR
|
---|
465 | CMP AL, "N" ; Non-stop
|
---|
466 | JE SHORT CMD_NONSTOP
|
---|
467 | CMP AL, "Q" ; Quit
|
---|
468 | JE CMD_QUIT
|
---|
469 | CMP AL, "R" ; Register
|
---|
470 | JE CMD_REG
|
---|
471 | CMP AL, "S" ; Search
|
---|
472 | JE CMD_SEARCH
|
---|
473 | CMP AL, "U" ; Unassemble
|
---|
474 | JE CMD_UNASSEMBLE
|
---|
475 | CMP AL, "V" ; Virtual
|
---|
476 | JE CMD_VIRT
|
---|
477 | CMP AL, "W" ; Watchpoint
|
---|
478 | JE CMD_WATCH
|
---|
479 | CMP AL, "X" ; Symbol
|
---|
480 | JE CMD_SYM
|
---|
481 | CMP AL, " " ; Step
|
---|
482 | JE CMD_STEP
|
---|
483 | BAD_KEY: MOV AL, 07H
|
---|
484 | CALL GCHAR
|
---|
485 | JMP KEY ; Wait for another command
|
---|
486 |
|
---|
487 | FKEY: CALL GINCHAR ; Get second code
|
---|
488 | CMP AL, 3CH ; F2
|
---|
489 | JE CMD_DOT
|
---|
490 | CMP AL, 3FH ; F5?
|
---|
491 | JE CONTINUE ; Yes -> continue program
|
---|
492 | CMP AL, 42H ; F8
|
---|
493 | JE DO_STEP
|
---|
494 | CMP AL, 44H ; F10
|
---|
495 | JE DO_CALL
|
---|
496 | JMP SHORT BAD_KEY ; Ring bell
|
---|
497 |
|
---|
498 | ;
|
---|
499 | ; Non-stop single stepping mode
|
---|
500 | ;
|
---|
501 | CMD_NONSTOP: MOV DEBUG_STOP, FALSE ; Set non-stop mode
|
---|
502 | JMP DO_STEP ; Continue program
|
---|
503 |
|
---|
504 | ;
|
---|
505 | ; Display registers
|
---|
506 | ;
|
---|
507 | CMD_DOT: CALL GCRLF ; New line
|
---|
508 | CALL REG_DUMP ; Display registers
|
---|
509 | MOV AL, 1 ; New disassembly
|
---|
510 | JMP SHOW ; Display current instruction
|
---|
511 |
|
---|
512 | ;
|
---|
513 | ; Multiple steps
|
---|
514 | ;
|
---|
515 | CMD_MULT: MOV DEBUG_COUNT, AH ; Set number of steps
|
---|
516 | JMP DO_STEP ; Continue program
|
---|
517 |
|
---|
518 | ;
|
---|
519 | ; Silent command
|
---|
520 | ;
|
---|
521 | CMD_SILENT: NOT DEBUG_SHOW_PC ; Toggle silent flag
|
---|
522 | JMP KEY ; Command loop
|
---|
523 |
|
---|
524 | ;
|
---|
525 | ; Go command
|
---|
526 | ;
|
---|
527 | CMD_GO: CALL INPUT ; Input arguments
|
---|
528 | JC INPUT_ERROR
|
---|
529 | CALL END_OF_LINE
|
---|
530 | JZ SHORT CONTINUE
|
---|
531 | MOV DX, I_CS
|
---|
532 | CALL GET_ADDR
|
---|
533 | JC INPUT_ERROR
|
---|
534 | CALL END_OF_LINE
|
---|
535 | JNZ INPUT_ERROR
|
---|
536 | ;
|
---|
537 | ; Breakpoint 0 at DX:EAX and continue program
|
---|
538 | ;
|
---|
539 | CALL SET_BREAKPOINT ; Set breakpoint 0 at DX:EAX
|
---|
540 | JNZ INPUT_ERROR ; Error -> display message
|
---|
541 | ;
|
---|
542 | ; Insert breakpoints and continue program
|
---|
543 | ;
|
---|
544 | CONTINUE: CMP DEBUG_FLAG, FALSE
|
---|
545 | JE SHORT CONT_0
|
---|
546 | LEA EDX, $CONTINUE
|
---|
547 | CALL GTEXT
|
---|
548 | CONT_0: MOV GO_FLAG, NOT FALSE ; GO command executing
|
---|
549 | CALL DEBUG_RESUME ; Resume program, don't step
|
---|
550 | CALL INS_BREAKPOINTS ; Insert breakpoints
|
---|
551 | JMP RUN ; Continue program
|
---|
552 |
|
---|
553 |
|
---|
554 | ;
|
---|
555 | ; Watchpoint command
|
---|
556 | ;
|
---|
557 | CMD_WATCH: CALL INPUT ; Input arguments
|
---|
558 | JC INPUT_ERROR
|
---|
559 | CALL END_OF_LINE ; Any arguments?
|
---|
560 | JZ CMD_BREAK_SHOW ; No -> display breakpoints
|
---|
561 | CALL FETCH ; Fetch character (length)
|
---|
562 | JZ INPUT_ERROR ; End of line -> error
|
---|
563 | MOV AH, 00H
|
---|
564 | CMP AL, "B"
|
---|
565 | JE SHORT CMD_WATCH_1
|
---|
566 | MOV AH, 01H
|
---|
567 | CMP AL, "W"
|
---|
568 | JE SHORT CMD_WATCH_1
|
---|
569 | MOV AH, 03H
|
---|
570 | CMP AL, "D"
|
---|
571 | JNE INPUT_ERROR
|
---|
572 | CMD_WATCH_1: MOV WP_LEN, AH
|
---|
573 | CALL FETCH ; Fetch character (type)
|
---|
574 | JZ INPUT_ERROR
|
---|
575 | MOV AH, BP_WATCHPOINT_R
|
---|
576 | CMP AL, "R"
|
---|
577 | JE SHORT CMD_WATCH_2
|
---|
578 | MOV AH, BP_WATCHPOINT_W
|
---|
579 | CMP AL, "W"
|
---|
580 | JE SHORT CMD_WATCH_2
|
---|
581 | MOV AH, BP_WATCHPOINT_X
|
---|
582 | CMP AL, "X"
|
---|
583 | JNE INPUT_ERROR
|
---|
584 | CMD_WATCH_2: MOV WP_TYPE, AH
|
---|
585 | CALL SKIP
|
---|
586 | MOV DX, I_DS
|
---|
587 | CALL GET_ADDR ; Get address
|
---|
588 | JC INPUT_ERROR
|
---|
589 | CALL END_OF_LINE
|
---|
590 | JNZ INPUT_ERROR
|
---|
591 | MOV BH, WP_LEN
|
---|
592 | MOV BL, WP_TYPE
|
---|
593 | TEST AL, BH
|
---|
594 | JNZ ALIGNMENT_ERROR
|
---|
595 | CALL SET_WATCHPOINT ; Set watchpoint
|
---|
596 | JNZ INPUT_ERROR
|
---|
597 | CALL SHOW_BREAKPOINT
|
---|
598 | JMP KEY ; Command loop
|
---|
599 |
|
---|
600 | ;
|
---|
601 | ; Breakpoint command
|
---|
602 | ;
|
---|
603 | CMD_BREAK: CALL INPUT ; Input arguments
|
---|
604 | JC INPUT_ERROR
|
---|
605 | CALL END_OF_LINE ; Any arguments?
|
---|
606 | JZ CMD_BREAK_SHOW ; No -> display breakpoints
|
---|
607 | MOV DX, I_CS
|
---|
608 | CALL GET_ADDR ; Get address
|
---|
609 | JC INPUT_ERROR
|
---|
610 | CALL END_OF_LINE
|
---|
611 | JNZ INPUT_ERROR
|
---|
612 | MOV BH, 0
|
---|
613 | MOV BL, BP_BREAKPOINT
|
---|
614 | CALL SET_WATCHPOINT ; Set breakpoint
|
---|
615 | JNZ INPUT_ERROR
|
---|
616 | CALL SHOW_BREAKPOINT
|
---|
617 | JMP KEY ; Command loop
|
---|
618 |
|
---|
619 | CMD_BREAK_SHOW: LEA SI, BREAKPOINTS
|
---|
620 | MOV CX, 4
|
---|
621 | CBS_1: CALL SHOW_BREAKPOINT
|
---|
622 | ADD SI, SIZE BREAKPOINT
|
---|
623 | LOOP CBS_1
|
---|
624 | JMP KEY
|
---|
625 |
|
---|
626 | ;
|
---|
627 | ; Delete breakpoint
|
---|
628 | ;
|
---|
629 | CMD_KILL: CALL INPUT ; Input arguments
|
---|
630 | JC INPUT_ERROR
|
---|
631 | CALL END_OF_LINE ; Any arguments?
|
---|
632 | JZ CMD_BREAK_SHOW ; No -> display breakpoints
|
---|
633 | CALL FETCH ; Fetch character (number)
|
---|
634 | JZ INPUT_ERROR ; End of line -> error
|
---|
635 | SUB AL, "0"
|
---|
636 | CMP AL, 3
|
---|
637 | JA INPUT_ERROR
|
---|
638 | MOV AH, SIZE BREAKPOINT
|
---|
639 | MUL AH
|
---|
640 | LEA SI, BREAKPOINTS
|
---|
641 | ADD SI, AX
|
---|
642 | CALL SKIP
|
---|
643 | CALL END_OF_LINE
|
---|
644 | JNZ INPUT_ERROR
|
---|
645 | MOV (BREAKPOINT PTR [SI]).BP_TYPE, BP_INACTIVE
|
---|
646 | JMP KEY
|
---|
647 |
|
---|
648 |
|
---|
649 | ;
|
---|
650 | ; Display breakpoint entry
|
---|
651 | ;
|
---|
652 | ; In: DS:SI Pointer to breakpoint entry
|
---|
653 | ;
|
---|
654 | ASSUME SI:PTR BREAKPOINT
|
---|
655 | SHOW_BREAKPOINT PROC NEAR
|
---|
656 | CMP [SI].BP_TYPE, BP_INACTIVE
|
---|
657 | JE SBP_RET
|
---|
658 | LEA AX, BREAKPOINTS
|
---|
659 | SUB AX, SI
|
---|
660 | NEG AX
|
---|
661 | MOV BX, SIZE BREAKPOINT
|
---|
662 | XOR DX, DX
|
---|
663 | DIV BX
|
---|
664 | ADD AL, "0"
|
---|
665 | CALL GCHAR
|
---|
666 | MOV AL, " "
|
---|
667 | CALL GCHAR
|
---|
668 | MOV AL, "B"
|
---|
669 | CMP [SI].BP_TYPE, BP_BREAKPOINT
|
---|
670 | JE SHORT SBP_1
|
---|
671 | MOV AL, "R"
|
---|
672 | CMP [SI].BP_TYPE, BP_WATCHPOINT_R
|
---|
673 | JE SHORT SBP_1
|
---|
674 | MOV AL, "W"
|
---|
675 | CMP [SI].BP_TYPE, BP_WATCHPOINT_W
|
---|
676 | JE SHORT SBP_1
|
---|
677 | MOV AL, "X"
|
---|
678 | CMP [SI].BP_TYPE, BP_WATCHPOINT_X
|
---|
679 | JE SHORT SBP_1
|
---|
680 | MOV AL, "?"
|
---|
681 | SBP_1: CALL GCHAR
|
---|
682 | CMP AL, "B"
|
---|
683 | MOV AL, " "
|
---|
684 | JE SHORT SBP_2
|
---|
685 | MOV AL, "B"
|
---|
686 | CMP [SI].BP_LEN, 00H
|
---|
687 | JE SHORT SBP_2
|
---|
688 | MOV AL, "W"
|
---|
689 | CMP [SI].BP_LEN, 01H
|
---|
690 | JE SHORT SBP_2
|
---|
691 | MOV AL, "D"
|
---|
692 | CMP [SI].BP_LEN, 03H
|
---|
693 | JE SHORT SBP_2
|
---|
694 | MOV AL, "?"
|
---|
695 | SBP_2: CALL GCHAR
|
---|
696 | MOV AL, " "
|
---|
697 | CALL GCHAR
|
---|
698 | MOV AX, [SI].BP_SEL
|
---|
699 | CALL GWORD
|
---|
700 | MOV AL, ":"
|
---|
701 | CALL GCHAR
|
---|
702 | MOV EAX, [SI].BP_OFF
|
---|
703 | CALL GDWORD
|
---|
704 | MOV AL, " "
|
---|
705 | CALL GCHAR
|
---|
706 | MOV EAX, [SI].BP_ADDR
|
---|
707 | CALL GDWORD
|
---|
708 | CALL GCRLF
|
---|
709 | SBP_RET: RET
|
---|
710 | ASSUME SI:NOTHING
|
---|
711 | SHOW_BREAKPOINT ENDP
|
---|
712 |
|
---|
713 |
|
---|
714 | ;
|
---|
715 | ; Unassemble
|
---|
716 | ;
|
---|
717 | CMD_UNASSEMBLE: CALL INPUT
|
---|
718 | JC INPUT_ERROR
|
---|
719 | MOV DX, U_LAST_SEL
|
---|
720 | OR DX, DX
|
---|
721 | JZ SHORT UAS01
|
---|
722 | CALL END_OF_LINE
|
---|
723 | MOV EAX, U_LAST_OFF
|
---|
724 | JZ UAS02
|
---|
725 | UAS01: MOV DX, I_CS
|
---|
726 | CALL GET_ADDR
|
---|
727 | JC INPUT_ERROR
|
---|
728 | CALL END_OF_LINE
|
---|
729 | JNZ INPUT_ERROR
|
---|
730 | UAS02: VERR DX
|
---|
731 | JNZ INVALID_SEL
|
---|
732 | MOV FS, DX
|
---|
733 | MOV ESI, EAX
|
---|
734 | MOV CX, 16
|
---|
735 | MOV DA_EMPTY_FLAG, FALSE
|
---|
736 | UAS1: CMP DA_EMPTY_FLAG, FALSE
|
---|
737 | JE SHORT UAS2
|
---|
738 | MOV DA_EMPTY_FLAG, FALSE
|
---|
739 | CALL GCRLF
|
---|
740 | JMP SHORT UAS3
|
---|
741 | UAS2: PUSH CX
|
---|
742 | CALL SHOW_DISASM
|
---|
743 | POP CX
|
---|
744 | UAS3: LOOP UAS1
|
---|
745 | MOV U_LAST_SEL, FS
|
---|
746 | MOV U_LAST_OFF, ESI
|
---|
747 | JMP KEY
|
---|
748 |
|
---|
749 | CMD_DISPLAY: CALL INPUT
|
---|
750 | JC INPUT_ERROR
|
---|
751 | MOV DX, D_LAST_SEL
|
---|
752 | OR DX, DX
|
---|
753 | JZ SHORT DISP00
|
---|
754 | CALL END_OF_LINE
|
---|
755 | MOV EAX, D_LAST_OFF
|
---|
756 | MOV ECX, 16
|
---|
757 | JZ SHORT DISP02
|
---|
758 | DISP00: MOV DX, I_DS
|
---|
759 | CALL GET_ADDR
|
---|
760 | JC INPUT_ERROR
|
---|
761 | CALL END_OF_LINE
|
---|
762 | JZ SHORT DISP01
|
---|
763 | CALL GET_RANGE_MORE
|
---|
764 | JC ERROR
|
---|
765 | CALL END_OF_LINE
|
---|
766 | JNZ INPUT_ERROR
|
---|
767 | ADD ECX, 15
|
---|
768 | SHR ECX, 4
|
---|
769 | JMP SHORT DISP02
|
---|
770 | DISP01: VERR DX
|
---|
771 | JNZ INVALID_SEL
|
---|
772 | MOV ECX, 16
|
---|
773 | DISP02: MOV FS, DX
|
---|
774 | MOV ESI, EAX
|
---|
775 | DISP10: CALL SHOW_DATA
|
---|
776 | ADD ESI, 16
|
---|
777 | DEC ECX
|
---|
778 | JNZ DISP10
|
---|
779 | MOV D_LAST_SEL, FS
|
---|
780 | MOV D_LAST_OFF, ESI
|
---|
781 | JMP KEY
|
---|
782 |
|
---|
783 | CMD_REG: CALL INPUT
|
---|
784 | JC INPUT_ERROR
|
---|
785 | CALL END_OF_LINE
|
---|
786 | JZ CMD_DOT
|
---|
787 | PUSH BX
|
---|
788 | CALL FETCH
|
---|
789 | JZ SHORT REG10
|
---|
790 | MOV AH, AL
|
---|
791 | CALL FETCH
|
---|
792 | JZ SHORT REG10
|
---|
793 | CALL SKIP
|
---|
794 | CALL END_OF_LINE
|
---|
795 | JNZ SHORT REG10
|
---|
796 | XCHG AL, AH
|
---|
797 | LEA BX, FLAG_TAB
|
---|
798 | REG01: MOV CX, [BX+0]
|
---|
799 | JCXZ REG10
|
---|
800 | CMP AX, [BX+2]
|
---|
801 | JE SHORT REG02
|
---|
802 | CMP AX, [BX+4]
|
---|
803 | JE SHORT REG03
|
---|
804 | ADD BX, 6
|
---|
805 | JMP SHORT REG01
|
---|
806 |
|
---|
807 | REG02: NOT CX
|
---|
808 | AND WORD PTR I_EFLAGS, CX
|
---|
809 | JMP SHORT REG04
|
---|
810 |
|
---|
811 | REG03: OR WORD PTR I_EFLAGS, CX
|
---|
812 | REG04: POP BX
|
---|
813 | JMP KEY
|
---|
814 |
|
---|
815 | REG10: POP BX
|
---|
816 | PUSH BX
|
---|
817 | CALL GET_REG
|
---|
818 | JC SHORT REG20
|
---|
819 | MOV CL, AL
|
---|
820 | MOV DI, DX
|
---|
821 | CMP BYTE PTR [BX], " "
|
---|
822 | JNE SHORT REG20
|
---|
823 | CALL SKIP
|
---|
824 | CALL GET_NUMBER
|
---|
825 | JC SHORT REG20
|
---|
826 | CALL SKIP
|
---|
827 | CALL END_OF_LINE
|
---|
828 | JNZ SHORT REG20
|
---|
829 | ;
|
---|
830 | ; CL = R8, R16, R32
|
---|
831 | ; DI = pointer to register in stack
|
---|
832 | ; EAX = value
|
---|
833 | ;
|
---|
834 | CMP CL, R8
|
---|
835 | JE SHORT REG10_8
|
---|
836 | CMP CL, R16
|
---|
837 | JE SHORT REG10_16
|
---|
838 | CMP CL, R32
|
---|
839 | JNE SHORT REG20
|
---|
840 | REG10_32: MOV SS:[DI], EAX
|
---|
841 | JMP SHORT REG11
|
---|
842 | REG10_16: TEST EAX, NOT 0FFFFH
|
---|
843 | JNZ SHORT REG10_ERROR
|
---|
844 | MOV SS:[DI], AX
|
---|
845 | JMP SHORT REG11
|
---|
846 | REG10_8: TEST EAX, NOT 0FFH
|
---|
847 | JNZ SHORT REG10_ERROR
|
---|
848 | MOV SS:[DI], AL
|
---|
849 | REG11: POP BX
|
---|
850 | JMP KEY
|
---|
851 |
|
---|
852 | REG10_ERROR: POP BX
|
---|
853 | JMP SHORT INPUT_ERROR
|
---|
854 |
|
---|
855 | REG20: POP BX
|
---|
856 | JMP SHORT INPUT_ERROR
|
---|
857 |
|
---|
858 | ALIGNMENT_ERROR:
|
---|
859 | LEA EDX, $ALIGNMENT
|
---|
860 | JMP SHORT ERROR
|
---|
861 |
|
---|
862 | BEYOND_LIMIT: LEA EDX, $BEYOND_LIMIT
|
---|
863 | JMP SHORT ERROR
|
---|
864 |
|
---|
865 | INVALID_SEL: LEA EDX, $INVALID_SEL
|
---|
866 | JMP SHORT ERROR
|
---|
867 |
|
---|
868 | INPUT_ERROR: LEA EDX, $INPUT_ERROR
|
---|
869 | ERROR: CALL GTEXT
|
---|
870 | JMP KEY
|
---|
871 |
|
---|
872 |
|
---|
873 | IF FLOATING_POINT
|
---|
874 | CMD_387: MOV SI, PROCESS_PTR
|
---|
875 | CMP SI, NO_PROCESS
|
---|
876 | JE BAD_KEY
|
---|
877 | ASSUME SI:PTR PROCESS
|
---|
878 | DB 66H
|
---|
879 | FNSAVE DWORD PTR [SI].P_CW ; Save FPU context, initialize
|
---|
880 | FWAIT
|
---|
881 | MOV DX, [SI].P_TW
|
---|
882 | MOV CX, [SI].P_SW
|
---|
883 | SHR CX, 11
|
---|
884 | AND CX, 7
|
---|
885 | ROR DX, CL
|
---|
886 | ROR DX, CL
|
---|
887 | LEA DI, [SI].P_FST
|
---|
888 | MOV CX, 8
|
---|
889 | FPU_1: PUSH DX
|
---|
890 | MOV AL, "S"
|
---|
891 | CALL GCHAR
|
---|
892 | MOV AL, "T"
|
---|
893 | CALL GCHAR
|
---|
894 | MOV AL, "("
|
---|
895 | CALL GCHAR
|
---|
896 | MOV AL, "8"
|
---|
897 | SUB AL, CL
|
---|
898 | CALL GCHAR
|
---|
899 | MOV AL, ")"
|
---|
900 | CALL GCHAR
|
---|
901 | MOV AL, "="
|
---|
902 | CALL GCHAR
|
---|
903 | MOV AX, DX
|
---|
904 | AND AX, 3
|
---|
905 | LEA EDX, $ZERO
|
---|
906 | DEC AX
|
---|
907 | JZ SHORT FPU_2
|
---|
908 | LEA EDX, $INFINITY
|
---|
909 | DEC AX
|
---|
910 | JZ SHORT FPU_2
|
---|
911 | LEA EDX, $EMPTY
|
---|
912 | DEC AX
|
---|
913 | JZ SHORT FPU_2
|
---|
914 | PUSH CX
|
---|
915 | PUSH DI
|
---|
916 | MOV CX, 10
|
---|
917 | ADD DI, CX
|
---|
918 | FPU_VALID_1: DEC DI
|
---|
919 | MOV AL, [DI]
|
---|
920 | CALL GBYTE
|
---|
921 | LOOP FPU_VALID_1
|
---|
922 | POP DI
|
---|
923 | POP CX
|
---|
924 | JMP SHORT FPU_3
|
---|
925 | FPU_2: CALL GTEXT
|
---|
926 | FPU_3: CALL GCRLF
|
---|
927 | POP DX
|
---|
928 | ROR DX, 2
|
---|
929 | ADD DI, 10
|
---|
930 | LOOP FPU_1
|
---|
931 | LEA EDX, $CW
|
---|
932 | CALL GTEXT
|
---|
933 | MOV AX, [SI].P_CW
|
---|
934 | CALL GWORD
|
---|
935 | LEA EDX, $SW
|
---|
936 | CALL GTEXT
|
---|
937 | MOV AX, [SI].P_SW
|
---|
938 | CALL GWORD
|
---|
939 | LEA EDX, $C3210
|
---|
940 | CALL GTEXT
|
---|
941 | MOV DX, 4000H
|
---|
942 | CALL FPU_C
|
---|
943 | MOV DX, 0400H
|
---|
944 | CALL FPU_C
|
---|
945 | MOV DX, 0200H
|
---|
946 | CALL FPU_C
|
---|
947 | MOV DX, 0100H
|
---|
948 | CALL FPU_C
|
---|
949 | MOV AX, [SI].P_SW
|
---|
950 | AND AX, 4500H
|
---|
951 | MOV DL, ">"
|
---|
952 | JZ SHORT FPU_4
|
---|
953 | CMP AX, 0100H
|
---|
954 | MOV DL, "<"
|
---|
955 | JE SHORT FPU_4
|
---|
956 | CMP AX, 4000H
|
---|
957 | JNE SHORT FPU_5
|
---|
958 | MOV DL, "="
|
---|
959 | FPU_4: MOV AL, " "
|
---|
960 | CALL GCHAR
|
---|
961 | MOV AL, DL
|
---|
962 | CALL GCHAR
|
---|
963 | FPU_5: CALL GCRLF
|
---|
964 | DB 66H
|
---|
965 | FRSTOR DWORD PTR [SI].P_CW
|
---|
966 | JMP KEY
|
---|
967 |
|
---|
968 | FPU_C PROC NEAR
|
---|
969 | MOV AL, "0"
|
---|
970 | TEST [SI].P_SW, DX
|
---|
971 | JZ SHORT FPU_C_1
|
---|
972 | INC AL
|
---|
973 | FPU_C_1: CALL GCHAR
|
---|
974 | RET
|
---|
975 | FPU_C ENDP
|
---|
976 |
|
---|
977 | ASSUME SI:NOTHING
|
---|
978 |
|
---|
979 | ELSE
|
---|
980 |
|
---|
981 | CMD_387: JMP BAD_KEY
|
---|
982 |
|
---|
983 | ENDIF
|
---|
984 |
|
---|
985 |
|
---|
986 | CMD_STEP: MOV FS, I_CS
|
---|
987 | MOV ESI, I_EIP
|
---|
988 | CALL GET_INST
|
---|
989 | CMP AL, 0CCH ; INT 3
|
---|
990 | JNE SHORT CMD_STEP_1
|
---|
991 | MOV I_EIP, ESI ; Skip INT 3
|
---|
992 | CALL GET_INST
|
---|
993 | CMD_STEP_1: CMP AL, 0CDH ; INT n
|
---|
994 | JE SHORT DO_CALL
|
---|
995 | ;
|
---|
996 | ; Single-step program
|
---|
997 | ;
|
---|
998 | DO_STEP: CMP DEBUG_FLAG, FALSE
|
---|
999 | JE SHORT DO_STEP_0
|
---|
1000 | LEA EDX, $DO_STEP
|
---|
1001 | CALL GTEXT
|
---|
1002 | DO_STEP_0: CALL DEBUG_STEP ; Set single step mode
|
---|
1003 | MOV SKIP_FLAG, NOT FALSE ; Ignore breakpoint at CS:EIP
|
---|
1004 | CALL INS_BREAKPOINTS ; Insert breakpoints
|
---|
1005 | MOV SKIP_FLAG, FALSE ; Restore original value
|
---|
1006 | JMP RUN ; Continue program
|
---|
1007 |
|
---|
1008 | ;
|
---|
1009 | ; Set breakpoint after current instruction, continue program
|
---|
1010 | ;
|
---|
1011 | CMD_CALL: MOV FS, I_CS
|
---|
1012 | MOV ESI, I_EIP
|
---|
1013 | CALL GET_INST
|
---|
1014 | CMP AL, 0CCH ; INT 3
|
---|
1015 | JNE SHORT CMD_CALL_1
|
---|
1016 | MOV I_EIP, ESI ; Skip INT 3
|
---|
1017 | CALL GET_INST
|
---|
1018 | CMD_CALL_1: CMP AL, 0C2H ; RETN immed
|
---|
1019 | JE SHORT DO_STEP
|
---|
1020 | CMP AL, 0C3H ; RETN
|
---|
1021 | JE SHORT DO_STEP
|
---|
1022 | CMP AL, 0CAH ; RETF immed
|
---|
1023 | JE SHORT DO_STEP
|
---|
1024 | CMP AL, 0CBH ; RETF
|
---|
1025 | JE SHORT DO_STEP
|
---|
1026 | CMP AL, 0CFH ; IRET/IRETD
|
---|
1027 | JE SHORT DO_STEP
|
---|
1028 | CMP AL, 0E9H ; JMP NEAR
|
---|
1029 | JE SHORT DO_STEP
|
---|
1030 | CMP AL, 0EAH ; JMP FAR
|
---|
1031 | JE SHORT DO_STEP
|
---|
1032 | CMP AL, 0EBH ; JMP SHORT
|
---|
1033 | JE SHORT DO_STEP
|
---|
1034 | CMP AL, 0FFH
|
---|
1035 | JE SHORT CMD_CALL_FF ; JMP reg/mem ?
|
---|
1036 | DO_CALL: CMP DEBUG_FLAG, FALSE
|
---|
1037 | JE SHORT DO_CALL_0
|
---|
1038 | LEA EDX, $DO_CALL
|
---|
1039 | CALL GTEXT
|
---|
1040 | DO_CALL_0: MOV FS, I_CS
|
---|
1041 | MOV ESI, I_EIP
|
---|
1042 | MOV ECX, ESI ; No relocation
|
---|
1043 | LEA DI, DISASM_BUF
|
---|
1044 | CALL GET_MODE
|
---|
1045 | CALL DISASM
|
---|
1046 | MOV DX, I_CS
|
---|
1047 | MOV EAX, ESI
|
---|
1048 | CALL SET_BREAKPOINT
|
---|
1049 | JMP CONTINUE
|
---|
1050 |
|
---|
1051 | CMD_CALL_FF: MOV AL, FS:[ESI] ; Get mod reg r/m byte
|
---|
1052 | AND AL, 7 SHL 3
|
---|
1053 | CMP AL, 4 SHL 3 ; JMP DWORD PTR reg/mem
|
---|
1054 | JE DO_STEP
|
---|
1055 | CMP AL, 5 SHL 3 ; JMP FWORD PTR reg/mem
|
---|
1056 | JE DO_STEP
|
---|
1057 | JMP SHORT DO_CALL
|
---|
1058 |
|
---|
1059 | CMD_SEARCH: CALL INPUT
|
---|
1060 | JC INPUT_ERROR
|
---|
1061 | CALL END_OF_LINE
|
---|
1062 | JZ INPUT_ERROR ; Future expansion: cont.
|
---|
1063 | MOV DX, I_DS
|
---|
1064 | CALL GET_RANGE
|
---|
1065 | JC ERROR
|
---|
1066 | MOV SEARCH_SEL, DX
|
---|
1067 | MOV SEARCH_OFF, EAX
|
---|
1068 | MOV SEARCH_LEN, ECX
|
---|
1069 | MOV SEARCH_SIZE, 0
|
---|
1070 | LEA DI, SEARCH_BUF
|
---|
1071 | CMD_SEARCH_01: CALL END_OF_LINE
|
---|
1072 | JZ SHORT CMD_SEARCH_09
|
---|
1073 | CMP SEARCH_SIZE, LENGTH SEARCH_BUF
|
---|
1074 | JAE INPUT_ERROR
|
---|
1075 | CMP BYTE PTR [BX], "'"
|
---|
1076 | JE SHORT CMD_SEARCH_02
|
---|
1077 | CALL GET_NUMBER
|
---|
1078 | JC INPUT_ERROR
|
---|
1079 | TEST EAX, NOT 0FFH
|
---|
1080 | JNZ INPUT_ERROR
|
---|
1081 | MOV [DI], AL
|
---|
1082 | INC DI
|
---|
1083 | INC SEARCH_SIZE
|
---|
1084 | CALL SKIP
|
---|
1085 | JMP SHORT CMD_SEARCH_01
|
---|
1086 |
|
---|
1087 | CMD_SEARCH_02: INC BX
|
---|
1088 | MOV AL, [BX]
|
---|
1089 | CMP AL, "'"
|
---|
1090 | JE SHORT CMD_SEARCH_04
|
---|
1091 | CMD_SEARCH_03: CALL END_OF_LINE
|
---|
1092 | JZ INPUT_ERROR
|
---|
1093 | MOV AL, [BX]
|
---|
1094 | INC BX
|
---|
1095 | CMP AL, "'"
|
---|
1096 | JE SHORT CMD_SEARCH_05
|
---|
1097 | CMD_SEARCH_04: CMP SEARCH_SIZE, LENGTH SEARCH_BUF
|
---|
1098 | JAE INPUT_ERROR
|
---|
1099 | MOV [DI], AL
|
---|
1100 | INC DI
|
---|
1101 | INC SEARCH_SIZE
|
---|
1102 | JMP SHORT CMD_SEARCH_03
|
---|
1103 |
|
---|
1104 | CMD_SEARCH_05: CALL DELIM
|
---|
1105 | JNZ INPUT_ERROR
|
---|
1106 | CALL SKIP
|
---|
1107 | JMP SHORT CMD_SEARCH_01
|
---|
1108 |
|
---|
1109 | CMD_SEARCH_09: CMP SEARCH_SIZE, 0
|
---|
1110 | JE INPUT_ERROR
|
---|
1111 | CMD_SEARCH_10: MOV ES, SEARCH_SEL
|
---|
1112 | CMD_SEARCH_11: MOV EDI, SEARCH_OFF
|
---|
1113 | MOV ECX, SEARCH_LEN
|
---|
1114 | MOV AL, SEARCH_BUF[0]
|
---|
1115 | REPNE SCAS BYTE PTR ES:[EDI]
|
---|
1116 | JNE SHORT CMD_SEARCH_99
|
---|
1117 | MOV SEARCH_OFF, EDI
|
---|
1118 | MOV SEARCH_LEN, ECX
|
---|
1119 | INC ECX
|
---|
1120 | CMP ECX, SEARCH_SIZE
|
---|
1121 | JB SHORT CMD_SEARCH_99
|
---|
1122 | MOV ECX, SEARCH_SIZE
|
---|
1123 | DEC ECX
|
---|
1124 | JZ SHORT CMD_SEARCH_12
|
---|
1125 | LEA ESI, SEARCH_BUF+1
|
---|
1126 | REPE CMPS BYTE PTR DS:[ESI], ES:[EDI]
|
---|
1127 | JNE SHORT CMD_SEARCH_11
|
---|
1128 | CMD_SEARCH_12: MOV ESI, SEARCH_OFF
|
---|
1129 | DEC ESI
|
---|
1130 | MOV FS, SEARCH_SEL
|
---|
1131 | CALL SHOW_DATA
|
---|
1132 | JMP SHORT CMD_SEARCH_10
|
---|
1133 |
|
---|
1134 | CMD_SEARCH_99: JMP KEY
|
---|
1135 |
|
---|
1136 | ;
|
---|
1137 | ; A command
|
---|
1138 | ;
|
---|
1139 | CMD_ADDR: CALL INPUT
|
---|
1140 | JC INPUT_ERROR
|
---|
1141 | CALL END_OF_LINE
|
---|
1142 | JZ INPUT_ERROR
|
---|
1143 | MOV DX, I_DS
|
---|
1144 | CALL GET_ADDR
|
---|
1145 | JC INPUT_ERROR
|
---|
1146 | MOV ADDR_COUNT, 0
|
---|
1147 | CALL END_OF_LINE
|
---|
1148 | JZ SHORT ADDR_1
|
---|
1149 | CALL GET_RANGE_MORE
|
---|
1150 | JC INPUT_ERROR
|
---|
1151 | CALL END_OF_LINE
|
---|
1152 | JNZ INPUT_ERROR
|
---|
1153 | MOV ADDR_COUNT, ECX
|
---|
1154 | ADDR_1: MOV ADDR_SEL, DX
|
---|
1155 | MOV ADDR_OFF, EAX
|
---|
1156 | VERR DX
|
---|
1157 | JNZ INVALID_SEL
|
---|
1158 | ADDR_LOOP: MOVZX EDX, ADDR_SEL
|
---|
1159 | LSL ECX, EDX
|
---|
1160 | CMP EAX, ECX
|
---|
1161 | JA BEYOND_LIMIT
|
---|
1162 | MOV AX, ADDR_SEL
|
---|
1163 | CALL GWORD
|
---|
1164 | MOV AL, ":"
|
---|
1165 | CALL GCHAR
|
---|
1166 | MOV EAX, ADDR_OFF
|
---|
1167 | CALL GDWORD
|
---|
1168 | MOV AL, " "
|
---|
1169 | CALL GCHAR
|
---|
1170 | MOV AX, ADDR_SEL
|
---|
1171 | MOV EBX, ADDR_OFF
|
---|
1172 | CALL GET_LIN
|
---|
1173 | LEA EDX, $ADDR_FAILURE
|
---|
1174 | JC SHORT ADDR_MSG
|
---|
1175 | MOV ADDR_LIN, EBX
|
---|
1176 | LEA EDX, $LINEAR
|
---|
1177 | CALL GTEXT
|
---|
1178 | CALL SHOW_LIN
|
---|
1179 | ADDR_NEXT: ADD ADDR_OFF, 1000H
|
---|
1180 | SUB ADDR_COUNT, 1000H
|
---|
1181 | JA ADDR_LOOP
|
---|
1182 | JMP KEY
|
---|
1183 |
|
---|
1184 | ADDR_MSG: CALL GTEXT
|
---|
1185 | JMP SHORT ADDR_NEXT
|
---|
1186 |
|
---|
1187 | ;
|
---|
1188 | ; V command
|
---|
1189 | ;
|
---|
1190 | CMD_VIRT: CALL INPUT
|
---|
1191 | JC INPUT_ERROR
|
---|
1192 | CALL END_OF_LINE
|
---|
1193 | JZ INPUT_ERROR
|
---|
1194 | MOV AL, [BX]
|
---|
1195 | CALL UPPER
|
---|
1196 | LEA DI, V_PHYS
|
---|
1197 | CMP AL, "P"
|
---|
1198 | JE VIRT_SCAN
|
---|
1199 | LEA DI, V_EXT
|
---|
1200 | CMP AL, "X"
|
---|
1201 | JE VIRT_SCAN
|
---|
1202 | CALL GET_NUMBER
|
---|
1203 | JC INPUT_ERROR
|
---|
1204 | MOV ADDR_LIN, EAX
|
---|
1205 | MOV ADDR_COUNT, 0
|
---|
1206 | CALL SKIP
|
---|
1207 | CALL END_OF_LINE
|
---|
1208 | JZ SHORT VIRT_LOOP
|
---|
1209 | CALL GET_NUMBER
|
---|
1210 | JC INPUT_ERROR
|
---|
1211 | CALL END_OF_LINE
|
---|
1212 | JNZ INPUT_ERROR
|
---|
1213 | SUB EAX, ADDR_LIN
|
---|
1214 | JB INPUT_ERROR
|
---|
1215 | INC EAX
|
---|
1216 | MOV ADDR_COUNT, EAX
|
---|
1217 | VIRT_LOOP: CALL SHOW_LIN
|
---|
1218 | ADD ADDR_LIN, 1000H
|
---|
1219 | SUB ADDR_COUNT, 1000H
|
---|
1220 | JA VIRT_LOOP
|
---|
1221 | JMP KEY
|
---|
1222 |
|
---|
1223 | ;
|
---|
1224 | ; VP and VX commands
|
---|
1225 | ;
|
---|
1226 | VIRT_SCAN: MOV LIST_ALL, NOT FALSE
|
---|
1227 | MOV ADDR_COUNT, 0
|
---|
1228 | INC BX
|
---|
1229 | CALL SKIP
|
---|
1230 | CALL END_OF_LINE
|
---|
1231 | JZ SHORT VSCAN_1
|
---|
1232 | MOV LIST_ALL, FALSE
|
---|
1233 | CALL GET_NUMBER
|
---|
1234 | JC INPUT_ERROR
|
---|
1235 | MOV ADDR_ARG, EAX
|
---|
1236 | CALL SKIP
|
---|
1237 | CALL END_OF_LINE
|
---|
1238 | JZ SHORT VSCAN_1
|
---|
1239 | CALL GET_NUMBER
|
---|
1240 | JC INPUT_ERROR
|
---|
1241 | CALL END_OF_LINE
|
---|
1242 | JNZ INPUT_ERROR
|
---|
1243 | SUB EAX, ADDR_ARG
|
---|
1244 | JB INPUT_ERROR
|
---|
1245 | INC EAX
|
---|
1246 | MOV ADDR_COUNT, EAX
|
---|
1247 | VSCAN_1: AND ADDR_ARG, NOT 0FFFH
|
---|
1248 | VSCAN_LOOP: CALL SCAN_PAGE_TABLES
|
---|
1249 | ADD ADDR_ARG, 1000H
|
---|
1250 | SUB ADDR_COUNT, 1000H
|
---|
1251 | JA VSCAN_LOOP
|
---|
1252 | JMP KEY
|
---|
1253 |
|
---|
1254 | V_PHYS PROC NEAR
|
---|
1255 | TEST AX, PAGE_PRESENT OR PAGE_ALLOC
|
---|
1256 | JZ SHORT V_PHYS_RET
|
---|
1257 | CMP LIST_ALL, FALSE
|
---|
1258 | JNE SHORT V_PHYS_SHOW
|
---|
1259 | AND EAX, NOT 0FFFH
|
---|
1260 | CMP EAX, ADDR_ARG
|
---|
1261 | JNE SHORT V_PHYS_RET
|
---|
1262 | V_PHYS_SHOW: CALL SHOW_LIN
|
---|
1263 | V_PHYS_RET: RET
|
---|
1264 | V_PHYS ENDP
|
---|
1265 |
|
---|
1266 | V_EXT PROC NEAR
|
---|
1267 | TEST DX, SWAP_ALLOC
|
---|
1268 | JNZ SHORT V_EXT_CMP
|
---|
1269 | MOV AX, DX
|
---|
1270 | AND AX, SRC_MASK
|
---|
1271 | CMP AX, SRC_EXEC
|
---|
1272 | JNE SHORT V_EXT_RET
|
---|
1273 | V_EXT_CMP: CMP LIST_ALL, FALSE
|
---|
1274 | JNE SHORT V_EXT_SHOW
|
---|
1275 | AND EDX, NOT 0FFFH
|
---|
1276 | CMP EDX, ADDR_ARG
|
---|
1277 | JNE SHORT V_EXT_RET
|
---|
1278 | V_EXT_SHOW: CALL SHOW_LIN
|
---|
1279 | V_EXT_RET: RET
|
---|
1280 | V_EXT ENDP
|
---|
1281 |
|
---|
1282 |
|
---|
1283 |
|
---|
1284 | SEL_TAB DW SEL_INVALID ; 0000 undefined
|
---|
1285 | DW SEL_TSS ; 0001 16-bit TSS
|
---|
1286 | DW SEL_LDT ; 0010 LDT
|
---|
1287 | DW SEL_TSS ; 0011 16-bit TSS (busy)
|
---|
1288 | DW SEL_CALL ; 0100 16-bit call gate
|
---|
1289 | DW SEL_TASK ; 0101 task gate
|
---|
1290 | DW SEL_INT ; 0110 16-bit interrupt gate
|
---|
1291 | DW SEL_TRAP ; 0111 16-bit trap gate
|
---|
1292 | DW SEL_INVALID ; 1000 undefined
|
---|
1293 | DW SEL_TSS ; 1001 32-bit TSS
|
---|
1294 | DW SEL_INVALID ; 1010 undefined
|
---|
1295 | DW SEL_TSS ; 1011 32-bit TSS (busy)
|
---|
1296 | DW SEL_CALL ; 1100 32-bit call gate
|
---|
1297 | DW SEL_INVALID ; 1101 undefined
|
---|
1298 | DW SEL_INT ; 1110 32-bit interrupt gate
|
---|
1299 | DW SEL_TRAP ; 1111 32-bit trap gate
|
---|
1300 |
|
---|
1301 | CMD_SELECTOR: CALL INPUT
|
---|
1302 | JC INPUT_ERROR
|
---|
1303 | CALL END_OF_LINE
|
---|
1304 | JZ INPUT_ERROR
|
---|
1305 | CALL GET_NUMBER
|
---|
1306 | JC INPUT_ERROR
|
---|
1307 | TEST EAX, NOT 0FFFFH
|
---|
1308 | JNZ INPUT_ERROR
|
---|
1309 | MOV SEL_SEL, AX
|
---|
1310 | MOV SEL_COUNT, 0
|
---|
1311 | CALL SKIP
|
---|
1312 | CALL END_OF_LINE
|
---|
1313 | JZ SHORT SEL_1
|
---|
1314 | CALL GET_NUMBER
|
---|
1315 | JC INPUT_ERROR
|
---|
1316 | SUB AX, SEL_SEL
|
---|
1317 | JB INPUT_ERROR
|
---|
1318 | SHR AX, 3
|
---|
1319 | INC AX
|
---|
1320 | MOV SEL_COUNT, AX
|
---|
1321 | CALL SKIP
|
---|
1322 | CALL END_OF_LINE
|
---|
1323 | JNZ INPUT_ERROR
|
---|
1324 | SEL_1:
|
---|
1325 | SEL_LOOP: MOV AX, SEL_SEL
|
---|
1326 | CALL GWORD
|
---|
1327 | LEA EDX, $RPL
|
---|
1328 | CALL GTEXT
|
---|
1329 | MOV AX, SEL_SEL
|
---|
1330 | AND AL, 03H
|
---|
1331 | ADD AL, "0"
|
---|
1332 | CALL GCHAR
|
---|
1333 | MOV AX, SEL_SEL
|
---|
1334 | LEA EDX, $TI_GDT
|
---|
1335 | MOV DI, G_GDT_MEM_SEL
|
---|
1336 | LEA SI, GDT
|
---|
1337 | TEST AX, 04H
|
---|
1338 | JZ SHORT SEL_2
|
---|
1339 | SLDT DI
|
---|
1340 | MOV SI, DI
|
---|
1341 | AND SI, NOT 07H
|
---|
1342 | SUB SI, G_LDT_SEL
|
---|
1343 | IMUL SI, LDT_ENTRIES
|
---|
1344 | LEA SI, LDTS[SI]
|
---|
1345 | LEA EDX, $TI_LDT
|
---|
1346 | SEL_2: CALL GTEXT
|
---|
1347 | AND DI, NOT 07H
|
---|
1348 | MOV AX, WORD PTR GDT[DI] ; ... ignore limit 16..19, G
|
---|
1349 | MOV BX, SEL_SEL
|
---|
1350 | OR BX, 07H
|
---|
1351 | CMP BX, AX
|
---|
1352 | JA SEL_INVALID
|
---|
1353 | AND BX, NOT 07H
|
---|
1354 | JZ SEL_NULL
|
---|
1355 | ADD SI, BX
|
---|
1356 | MOV BX, [SI+5]
|
---|
1357 | TEST BX, 10H ; D1
|
---|
1358 | JNZ SHORT SEL_SEG
|
---|
1359 | MOV DI, BX
|
---|
1360 | AND DI, 0FH
|
---|
1361 | SHL DI, 1
|
---|
1362 | JMP SEL_TAB[DI]
|
---|
1363 |
|
---|
1364 | SEL_LDT: LEA EDX, $LDT
|
---|
1365 | CALL GTEXT
|
---|
1366 | CALL SEL_DPL_P
|
---|
1367 | JMP SHORT SEL_SEG_1
|
---|
1368 |
|
---|
1369 | ;
|
---|
1370 | ; It's a segment
|
---|
1371 | ;
|
---|
1372 | SEL_SEG: TEST BX, 08H ; Code segment?
|
---|
1373 | JNZ SHORT SEL_CODE
|
---|
1374 | LEA EDX, $DATA
|
---|
1375 | CALL GTEXT
|
---|
1376 | CALL SEL_DPL_P
|
---|
1377 | MOV AL, "A"
|
---|
1378 | TEST BX, 01H ; Accessed
|
---|
1379 | CALL SHOW_BIT
|
---|
1380 | MOV AL, "W"
|
---|
1381 | TEST BX, 02H ; Writable?
|
---|
1382 | CALL SHOW_BIT
|
---|
1383 | MOV AL, "E"
|
---|
1384 | TEST BX, 04H ; Expand down?
|
---|
1385 | CALL SHOW_BIT
|
---|
1386 | MOV AL, "B"
|
---|
1387 | TEST BX, 4000H ; Big?
|
---|
1388 | CALL SHOW_BIT
|
---|
1389 | SEL_SEG_1: MOV AL, "G"
|
---|
1390 | TEST BX, 8000H ; Granularity?
|
---|
1391 | CALL SHOW_BIT
|
---|
1392 | LEA EDX, $BASE
|
---|
1393 | CALL GTEXT
|
---|
1394 | MOV AH, [SI+7]
|
---|
1395 | MOV AL, [SI+4]
|
---|
1396 | SHL EAX, 16
|
---|
1397 | MOV AX, [SI+2]
|
---|
1398 | CALL GDWORD
|
---|
1399 | LEA EDX, $LIMIT
|
---|
1400 | CALL GTEXT
|
---|
1401 | MOV AL, [SI+6]
|
---|
1402 | AND AX, 0FH
|
---|
1403 | SHL EAX, 16
|
---|
1404 | MOV AX, [SI+0]
|
---|
1405 | TEST BX, 8000H ; Granularity
|
---|
1406 | JZ SHORT SEL_LIMIT_1
|
---|
1407 | SHL EAX, 12
|
---|
1408 | OR EAX, 0FFFH
|
---|
1409 | SEL_LIMIT_1: CALL GDWORD
|
---|
1410 | JMP SEL_DONE
|
---|
1411 |
|
---|
1412 | SEL_CODE: LEA EDX, $CODE
|
---|
1413 | CALL GTEXT
|
---|
1414 | CALL SEL_DPL_P
|
---|
1415 | MOV AL, "A"
|
---|
1416 | TEST BX, 01H ; Accessed
|
---|
1417 | CALL SHOW_BIT
|
---|
1418 | MOV AL, "R"
|
---|
1419 | TEST BX, 02H ; Readable?
|
---|
1420 | CALL SHOW_BIT
|
---|
1421 | MOV AL, "C"
|
---|
1422 | TEST BX, 04H ; Conforming?
|
---|
1423 | CALL SHOW_BIT
|
---|
1424 | MOV AL, "D"
|
---|
1425 | TEST BX, 4000H ; Default?
|
---|
1426 | CALL SHOW_BIT
|
---|
1427 | JMP SEL_SEG_1
|
---|
1428 |
|
---|
1429 | SEL_TRAP: LEA EDX, $TRAP
|
---|
1430 | JMP SHORT SEL_INT_1
|
---|
1431 |
|
---|
1432 | SEL_INT: LEA EDX, $INT
|
---|
1433 | SEL_INT_1: CALL SEL_16_32
|
---|
1434 | CALL GTEXT
|
---|
1435 | CALL SEL_DPL_P
|
---|
1436 | MOV AX, [SI+2]
|
---|
1437 | CALL GWORD
|
---|
1438 | MOV AL, ":"
|
---|
1439 | CALL GCHAR
|
---|
1440 | XOR EAX, EAX
|
---|
1441 | TEST BX, 08H
|
---|
1442 | JZ SHORT SEL_INT_2
|
---|
1443 | MOV AX, [SI+6]
|
---|
1444 | SHL EAX, 16
|
---|
1445 | SEL_INT_2: MOV AX, [SI+0]
|
---|
1446 | CALL GDWORD
|
---|
1447 | JMP SEL_DONE
|
---|
1448 |
|
---|
1449 | SEL_TSS: CALL SEL_16_32
|
---|
1450 | LEA EDX, $TSS
|
---|
1451 | CALL GTEXT
|
---|
1452 | CALL SEL_DPL_P
|
---|
1453 | MOV AL, "B"
|
---|
1454 | TEST BX, 02H ; Busy
|
---|
1455 | CALL SHOW_BIT
|
---|
1456 | JMP SEL_SEG_1
|
---|
1457 |
|
---|
1458 | SEL_CALL: CALL SEL_16_32
|
---|
1459 | LEA EDX, $CALL
|
---|
1460 | CALL GTEXT
|
---|
1461 | CALL SEL_DPL_P
|
---|
1462 | MOV AX, [SI+2]
|
---|
1463 | CALL GWORD
|
---|
1464 | MOV AL, ":"
|
---|
1465 | CALL GCHAR
|
---|
1466 | XOR EAX, EAX
|
---|
1467 | TEST BX, 08H
|
---|
1468 | JZ SHORT SEL_CALL_1
|
---|
1469 | MOV AX, [SI+6]
|
---|
1470 | SHL EAX, 16
|
---|
1471 | SEL_CALL_1: MOV AX, [SI+0]
|
---|
1472 | CALL GDWORD
|
---|
1473 | MOV AL, " "
|
---|
1474 | MOV AL, [SI+4]
|
---|
1475 | AND AL, 0FH
|
---|
1476 | CALL GBYTE
|
---|
1477 | JMP SHORT SEL_DONE
|
---|
1478 |
|
---|
1479 | SEL_TASK: LEA EDX, $TASK
|
---|
1480 | CALL GTEXT
|
---|
1481 | CALL SEL_DPL_P
|
---|
1482 | MOV AX, [SI+2]
|
---|
1483 | CALL GWORD
|
---|
1484 | JMP SHORT SEL_DONE
|
---|
1485 |
|
---|
1486 | SEL_NULL: LEA EDX, $NULL
|
---|
1487 | CALL GTEXT
|
---|
1488 | JMP SHORT SEL_DONE
|
---|
1489 |
|
---|
1490 | SEL_INVALID: LEA EDX, $SEL_INVALID
|
---|
1491 | CALL GTEXT
|
---|
1492 | SEL_DONE: CALL GCRLF
|
---|
1493 | ADD SEL_SEL, 8
|
---|
1494 | SUB SEL_COUNT, 1
|
---|
1495 | JA SEL_LOOP
|
---|
1496 | JMP KEY
|
---|
1497 |
|
---|
1498 |
|
---|
1499 | SEL_16_32 PROC NEAR
|
---|
1500 | PUSH EDX
|
---|
1501 | LEA EDX, $SEL_32
|
---|
1502 | TEST BX, 08H
|
---|
1503 | JNZ SHORT SEL_16_32_1
|
---|
1504 | LEA EDX, $SEL_16
|
---|
1505 | SEL_16_32_1: CALL GTEXT
|
---|
1506 | POP EDX
|
---|
1507 | RET
|
---|
1508 | SEL_16_32 ENDP
|
---|
1509 |
|
---|
1510 | SEL_DPL_P PROC NEAR
|
---|
1511 | PUSH EDX
|
---|
1512 | LEA EDX, $DPL
|
---|
1513 | CALL GTEXT
|
---|
1514 | MOV AX, BX
|
---|
1515 | SHR AX, 5
|
---|
1516 | AND AL, 03H
|
---|
1517 | ADD AL, "0"
|
---|
1518 | CALL GCHAR
|
---|
1519 | MOV AL, " "
|
---|
1520 | CALL GCHAR
|
---|
1521 | MOV AL, "P"
|
---|
1522 | TEST BX, 80H
|
---|
1523 | CALL SHOW_BIT
|
---|
1524 | MOV AL, " "
|
---|
1525 | CALL GCHAR
|
---|
1526 | POP EDX
|
---|
1527 | RET
|
---|
1528 | SEL_DPL_P ENDP
|
---|
1529 |
|
---|
1530 | ;
|
---|
1531 | ; Quit
|
---|
1532 | ;
|
---|
1533 | CMD_QUIT: CALL INPUT
|
---|
1534 | JC INPUT_ERROR
|
---|
1535 | CALL END_OF_LINE
|
---|
1536 | MOV AL, 0
|
---|
1537 | JZ CMD_QUIT_0
|
---|
1538 | CALL GET_NUMBER
|
---|
1539 | JC INPUT_ERROR
|
---|
1540 | TEST EAX, NOT 0FFH
|
---|
1541 | JNZ INPUT_ERROR
|
---|
1542 | CMD_QUIT_0: MOV AH, 4CH
|
---|
1543 | INT 21H
|
---|
1544 | JMP SHORT $
|
---|
1545 |
|
---|
1546 |
|
---|
1547 | ;
|
---|
1548 | ; Symbol
|
---|
1549 | ;
|
---|
1550 | CMD_SYM: CALL INPUT
|
---|
1551 | JC INPUT_ERROR
|
---|
1552 | CALL GET_NUMBER
|
---|
1553 | JC INPUT_ERROR
|
---|
1554 | MOV EDX, EAX
|
---|
1555 | CALL END_OF_LINE
|
---|
1556 | JNZ INPUT_ERROR
|
---|
1557 | MOV DI, PROCESS_PTR
|
---|
1558 | CALL SYM_BEFORE
|
---|
1559 | JC KEY
|
---|
1560 | CALL GDWORD
|
---|
1561 | MOV AL, " "
|
---|
1562 | CALL GCHAR
|
---|
1563 | CALL PRINT_SYM
|
---|
1564 | CALL GCRLF
|
---|
1565 | JMP KEY
|
---|
1566 |
|
---|
1567 | ;
|
---|
1568 | ; Info
|
---|
1569 | ;
|
---|
1570 | CMD_INFO: CALL INPUT
|
---|
1571 | JC INPUT_ERROR
|
---|
1572 | CALL END_OF_LINE
|
---|
1573 | JNZ INPUT_ERROR
|
---|
1574 | LEA EDX, $INFO_TITLE
|
---|
1575 | CALL GTEXT
|
---|
1576 | LEA BX, PROCESS_TABLE
|
---|
1577 | ASSUME BX:PTR PROCESS
|
---|
1578 | MOV CX, MAX_PROCESSES + 1
|
---|
1579 | INFO_10: CMP [BX].P_STATUS, PS_NONE ; Empty slot?
|
---|
1580 | JE SHORT INFO_19
|
---|
1581 | MOV AL, [BX].P_PIDX
|
---|
1582 | CALL GBYTE
|
---|
1583 | MOV AL, " "
|
---|
1584 | CMP BX, PROCESS_PTR
|
---|
1585 | JNE SHORT INFO_13
|
---|
1586 | MOV AL, "*"
|
---|
1587 | INFO_13: CALL GCHAR
|
---|
1588 | MOV AL, " "
|
---|
1589 | CALL GCHAR
|
---|
1590 | MOV EAX, [BX].P_PID
|
---|
1591 | CALL GDWORD
|
---|
1592 | MOV AL, " "
|
---|
1593 | CALL GCHAR
|
---|
1594 | MOV EAX, [BX].P_PPID
|
---|
1595 | CALL GDWORD
|
---|
1596 | ;
|
---|
1597 | ; File handles
|
---|
1598 | ;
|
---|
1599 | MOV SI, 0
|
---|
1600 | INFO_LOOP_HANDLE:
|
---|
1601 | MOV AL, " "
|
---|
1602 | CALL GCHAR
|
---|
1603 | MOV AX, [BX].P_HANDLES[SI]
|
---|
1604 | CMP AX, NO_FILE_HANDLE
|
---|
1605 | JE SHORT INFO_NO_HANDLE
|
---|
1606 | AAM
|
---|
1607 | XCHG AL, AH
|
---|
1608 | ADD AL, "0"
|
---|
1609 | CALL GCHAR
|
---|
1610 | XCHG AL, AH
|
---|
1611 | ADD AL, "0"
|
---|
1612 | CALL GCHAR
|
---|
1613 | JMP SHORT INFO_NEXT_HANDLE
|
---|
1614 |
|
---|
1615 | INFO_NO_HANDLE: MOV AL, "-"
|
---|
1616 | CALL GCHAR
|
---|
1617 | CALL GCHAR
|
---|
1618 | INFO_NEXT_HANDLE:
|
---|
1619 | ADD SI, 2
|
---|
1620 | CMP SI, 2 * 19
|
---|
1621 | JB SHORT INFO_LOOP_HANDLE
|
---|
1622 | CALL GCRLF
|
---|
1623 | ;
|
---|
1624 | ; Next process table entry
|
---|
1625 | ;
|
---|
1626 | INFO_19: ADD BX, SIZE PROCESS
|
---|
1627 | DEC CX
|
---|
1628 | JNZ INFO_10
|
---|
1629 | ASSUME BX:NOTHING
|
---|
1630 | CALL CHECK_HANDLES
|
---|
1631 | JMP KEY
|
---|
1632 |
|
---|
1633 | ;
|
---|
1634 | ; Continue program
|
---|
1635 | ;
|
---|
1636 | RUN: CMP DEBUG_FLAG, FALSE
|
---|
1637 | JE SHORT RUN_0
|
---|
1638 | LEA EDX, $RUN
|
---|
1639 | CALL GTEXT
|
---|
1640 | RUN_0: JMP EXCEPT_RET
|
---|
1641 | ASSUME BP:NOTHING
|
---|
1642 | DEBUG_EXCEPTION ENDP
|
---|
1643 |
|
---|
1644 |
|
---|
1645 | ;
|
---|
1646 | ; Get next instruction opcode byte, skip prefix bytes
|
---|
1647 | ;
|
---|
1648 | ; In: FS:ESI Pointer to code
|
---|
1649 | ;
|
---|
1650 | ; Out: AL Opcode byte
|
---|
1651 | ; ESI Points to next opcode byte
|
---|
1652 | ;
|
---|
1653 | GET_INST PROC NEAR
|
---|
1654 | GINST1: MOV AL, FS:[ESI]
|
---|
1655 | INC ESI
|
---|
1656 | CMP AL, 26H ; ES prefix
|
---|
1657 | JE SHORT GINST1
|
---|
1658 | CMP AL, 2EH ; CS prefix
|
---|
1659 | JE SHORT GINST1
|
---|
1660 | CMP AL, 36H ; SS prefix
|
---|
1661 | JE SHORT GINST1
|
---|
1662 | CMP AL, 3EH ; DS prefix
|
---|
1663 | JE SHORT GINST1
|
---|
1664 | CMP AL, 64H ; FS prefix
|
---|
1665 | JE SHORT GINST1
|
---|
1666 | CMP AL, 65H ; GS prefix
|
---|
1667 | JE SHORT GINST1
|
---|
1668 | CMP AL, 66H ; Operand size prefix
|
---|
1669 | JE SHORT GINST1
|
---|
1670 | CMP AL, 67H ; Adress size prefix
|
---|
1671 | JE SHORT GINST1
|
---|
1672 | CMP AL, 0F0H ; LOCK prefix
|
---|
1673 | JE SHORT GINST1
|
---|
1674 | CMP AL, 0F2H ; REP/REPNE prefix
|
---|
1675 | JE SHORT GINST1
|
---|
1676 | CMP AL, 0F3H ; REPE prefix
|
---|
1677 | JE SHORT GINST1
|
---|
1678 | RET
|
---|
1679 | GET_INST ENDP
|
---|
1680 |
|
---|
1681 | ;
|
---|
1682 | ; In: AL=0 Display empty line if jumped
|
---|
1683 | ; AL!=0 Don't display empty line
|
---|
1684 | ;
|
---|
1685 | ASSUME BP:PTR ISTACKFRAME
|
---|
1686 | TRACE_DISASM PROC NEAR
|
---|
1687 | OR AL, AL ; Stopped?
|
---|
1688 | MOV AX, I_CS ; Get CS:EIP
|
---|
1689 | MOV ESI, I_EIP
|
---|
1690 | JNZ SHORT TDA2 ; Yes -> no empty line
|
---|
1691 | CMP AX, NEXT_CS ; Are we at next instruction?
|
---|
1692 | JNE SHORT TDA1 ; No -> empty line
|
---|
1693 | CMP ESI, NEXT_EIP
|
---|
1694 | JE SHORT TDA2 ; Yes -> no empty line
|
---|
1695 | TDA1: CALL GCRLF ; Display empty line
|
---|
1696 | TDA2: MOV FS, AX
|
---|
1697 | CALL SHOW_DISASM ; One line of disassembly
|
---|
1698 | MOV NEXT_CS, FS ; Remember address of
|
---|
1699 | MOV NEXT_EIP, ESI ; next instruction
|
---|
1700 | RET
|
---|
1701 | ASSUME BP:NOTHING
|
---|
1702 | TRACE_DISASM ENDP
|
---|
1703 |
|
---|
1704 |
|
---|
1705 | SHOW_DISASM PROC NEAR
|
---|
1706 | XOR EAX, EAX
|
---|
1707 | MOV AX, FS
|
---|
1708 | LSL EAX, EAX
|
---|
1709 | CMP ESI, EAX
|
---|
1710 | JA SDIS_RET
|
---|
1711 | PUSH ESI
|
---|
1712 | MOV ECX, ESI ; No relocation
|
---|
1713 | LEA DI, DISASM_BUF
|
---|
1714 | CALL GET_MODE
|
---|
1715 | CALL DISASM
|
---|
1716 | MOV DA_SYM_FLAG, AL
|
---|
1717 | MOV DA_EMPTY_FLAG, AH
|
---|
1718 | MOV DA_SYM_ADDR, EDX
|
---|
1719 | MOV AX, FS
|
---|
1720 | CMP AX, L_CODE_SEL ; Symbols only for L_CODE_SEL
|
---|
1721 | JNE SHORT SDIS_S9
|
---|
1722 | POP EDX
|
---|
1723 | PUSH EDX
|
---|
1724 | MOV AL, SYM_LINE
|
---|
1725 | MOV DI, PROCESS_PTR
|
---|
1726 | CALL SYM_BY_ADDR
|
---|
1727 | JC SHORT SDIS_S2
|
---|
1728 | POP EAX
|
---|
1729 | PUSH EAX
|
---|
1730 | PUSH DX
|
---|
1731 | MOV EDX, EAX
|
---|
1732 | CALL SYM_MODULE
|
---|
1733 | JC SHORT SDIS_S1
|
---|
1734 | CALL PRINT_SYM
|
---|
1735 | SDIS_S1: LEA EDX, $LINE
|
---|
1736 | CALL GTEXT
|
---|
1737 | POP AX
|
---|
1738 | MOVZX EAX, AX
|
---|
1739 | CALL DECIMAL
|
---|
1740 | MOV AL, ":"
|
---|
1741 | CALL GCHAR
|
---|
1742 | CALL GCRLF
|
---|
1743 | SDIS_S2: POP EDX
|
---|
1744 | PUSH EDX
|
---|
1745 | MOV AL, SYM_TEXT
|
---|
1746 | CALL SYM_BY_ADDR
|
---|
1747 | JC SHORT SDIS_S9
|
---|
1748 | CALL PRINT_SYM
|
---|
1749 | MOV AL, ":"
|
---|
1750 | CALL GCHAR
|
---|
1751 | CALL GCRLF
|
---|
1752 | SDIS_S9: POP EBX
|
---|
1753 | MOV AX, FS
|
---|
1754 | CALL GWORD
|
---|
1755 | MOV AL, ":"
|
---|
1756 | CALL GCHAR
|
---|
1757 | MOV EAX, EBX
|
---|
1758 | CALL GDWORD
|
---|
1759 | MOV AL, " "
|
---|
1760 | CALL GCHAR
|
---|
1761 | MOV CX, 8
|
---|
1762 | LEA EDX, DISASM_BUF
|
---|
1763 | SDIS1: CMP EBX, ESI
|
---|
1764 | JAE SHORT SDIS5
|
---|
1765 | OR CX, CX
|
---|
1766 | JNZ SHORT SDIS4
|
---|
1767 | CALL SDIS_DIS
|
---|
1768 | MOV AL, " "
|
---|
1769 | MOV CX, 14
|
---|
1770 | SDIS2: CALL GCHAR
|
---|
1771 | LOOP SDIS2
|
---|
1772 | MOV CX, 8
|
---|
1773 | SDIS4: MOV AL, FS:[EBX]
|
---|
1774 | CALL GBYTE
|
---|
1775 | INC EBX
|
---|
1776 | DEC CX
|
---|
1777 | JMP SHORT SDIS1
|
---|
1778 |
|
---|
1779 | SDIS5: JCXZ SDIS7
|
---|
1780 | MOV AL, " "
|
---|
1781 | SDIS6: CALL GCHAR
|
---|
1782 | CALL GCHAR
|
---|
1783 | LOOP SDIS6
|
---|
1784 | SDIS7: CALL SDIS_DIS
|
---|
1785 | SDIS_RET: RET
|
---|
1786 |
|
---|
1787 | SDIS_DIS PROC NEAR
|
---|
1788 | PUSH EBX
|
---|
1789 | OR EDX, EDX
|
---|
1790 | JZ SHORT SDIS_DIS9
|
---|
1791 | MOV AL, " "
|
---|
1792 | CALL GCHAR
|
---|
1793 | CALL GTEXT
|
---|
1794 | MOV AX, FS
|
---|
1795 | CMP AX, L_CODE_SEL ; Symbols only for L_CODE_SEL
|
---|
1796 | JNE SHORT SDIS_DIS9
|
---|
1797 | MOV AL, DA_SYM_FLAG
|
---|
1798 | CMP AL, SYM_NONE
|
---|
1799 | JE SHORT SDIS_DIS9
|
---|
1800 | MOV EDX, DA_SYM_ADDR
|
---|
1801 | CMP EDX, 2
|
---|
1802 | JB SHORT SDIS_DIS9 ; Avoid symbols for 0, 1
|
---|
1803 | MOV DI, PROCESS_PTR
|
---|
1804 | CALL SYM_BY_ADDR
|
---|
1805 | JC SHORT SDIS_DIS9
|
---|
1806 | MOV AL, " "
|
---|
1807 | CALL GCHAR
|
---|
1808 | CALL GCHAR
|
---|
1809 | MOV AL, ";"
|
---|
1810 | CALL GCHAR
|
---|
1811 | MOV AL, " "
|
---|
1812 | CALL GCHAR
|
---|
1813 | CALL PRINT_SYM
|
---|
1814 | SDIS_DIS9: CALL GCRLF
|
---|
1815 | XOR EDX, EDX
|
---|
1816 | POP EBX
|
---|
1817 | RET
|
---|
1818 | SDIS_DIS ENDP
|
---|
1819 |
|
---|
1820 | SHOW_DISASM ENDP
|
---|
1821 |
|
---|
1822 | ;
|
---|
1823 | ; Display a symbol
|
---|
1824 | ;
|
---|
1825 | ; In: ES:EBX Name of symbol
|
---|
1826 | ;
|
---|
1827 | PRINT_SYM PROC NEAR
|
---|
1828 | PUSH EDX
|
---|
1829 | PUSH DI
|
---|
1830 | LEA DI, SYMBOL_BUF
|
---|
1831 | PSYM1: MOV AL, ES:[EBX]
|
---|
1832 | MOV [DI], AL
|
---|
1833 | INC EBX
|
---|
1834 | INC DI
|
---|
1835 | OR AL, AL
|
---|
1836 | JNZ SHORT PSYM1
|
---|
1837 | LEA EDX, SYMBOL_BUF
|
---|
1838 | CALL GTEXT
|
---|
1839 | POP DI
|
---|
1840 | POP EDX
|
---|
1841 | RET
|
---|
1842 | PRINT_SYM ENDP
|
---|
1843 |
|
---|
1844 |
|
---|
1845 | ;
|
---|
1846 | ; Get 16/32 mode for disassembler
|
---|
1847 | ;
|
---|
1848 | ; In: FS Segment register
|
---|
1849 | ;
|
---|
1850 | ; Out: AL 0:16, 1:32
|
---|
1851 | ; EAX Changed
|
---|
1852 | ;
|
---|
1853 | GET_MODE PROC NEAR
|
---|
1854 | XOR EAX, EAX
|
---|
1855 | MOV AX, FS
|
---|
1856 | LAR EAX, EAX ; Ignore flags
|
---|
1857 | TEST EAX, 1 SHL 22
|
---|
1858 | SETNZ AL
|
---|
1859 | RET
|
---|
1860 | GET_MODE ENDP
|
---|
1861 |
|
---|
1862 |
|
---|
1863 | ;
|
---|
1864 | ; Display the status of a bit: upper case if set, lower case if clear
|
---|
1865 | ;
|
---|
1866 | ; In: NZ Bit is set
|
---|
1867 | ; AL Upper case character
|
---|
1868 | ;
|
---|
1869 | SHOW_BIT PROC NEAR
|
---|
1870 | JNZ SHORT SHOW_BIT_1
|
---|
1871 | ADD AL, "a" - "A"
|
---|
1872 | SHOW_BIT_1: CALL GCHAR
|
---|
1873 | RET
|
---|
1874 | SHOW_BIT ENDP
|
---|
1875 |
|
---|
1876 |
|
---|
1877 |
|
---|
1878 |
|
---|
1879 | ;
|
---|
1880 | ; Bug: pages protected by swapper cause exception 0EH (and dump)
|
---|
1881 | ;
|
---|
1882 | SHOW_DATA PROC NEAR
|
---|
1883 | PUSHAD
|
---|
1884 | MOV AX, FS
|
---|
1885 | CALL GWORD
|
---|
1886 | MOV AL, ":"
|
---|
1887 | CALL GCHAR
|
---|
1888 | MOV EAX, ESI
|
---|
1889 | CALL GDWORD
|
---|
1890 | MOV AL," "
|
---|
1891 | CALL GCHAR
|
---|
1892 | XOR EDX, EDX
|
---|
1893 | MOV DX, FS
|
---|
1894 | LSL EDX, EDX
|
---|
1895 | MOV CX, 16
|
---|
1896 | SDATA11: CMP ESI, EDX
|
---|
1897 | JA SHORT SDATA12
|
---|
1898 | MOV AL, FS:[ESI]
|
---|
1899 | CALL GBYTE
|
---|
1900 | JMP SHORT SDATA13
|
---|
1901 | SDATA12: MOV AL, " "
|
---|
1902 | CALL GCHAR
|
---|
1903 | CALL GCHAR
|
---|
1904 | SDATA13: MOV AL, " "
|
---|
1905 | CALL GCHAR
|
---|
1906 | INC ESI
|
---|
1907 | LOOP SDATA11
|
---|
1908 | MOV AL, " "
|
---|
1909 | CALL GCHAR
|
---|
1910 | SUB ESI, 16
|
---|
1911 | MOV CX, 16
|
---|
1912 | SDATA21: CMP ESI, EDX
|
---|
1913 | JA SHORT SDATA29
|
---|
1914 | MOV AL, FS:[ESI]
|
---|
1915 | INC ESI
|
---|
1916 | CMP AL, 20H
|
---|
1917 | JB SHORT SDATA22
|
---|
1918 | CMP AL, 7FH
|
---|
1919 | JB SHORT SDATA23
|
---|
1920 | SDATA22: MOV AL, "."
|
---|
1921 | SDATA23: CALL GCHAR
|
---|
1922 | LOOP SDATA21
|
---|
1923 | SDATA29: CALL GCRLF
|
---|
1924 | POPAD
|
---|
1925 | NOP ; Avoid 386 bug
|
---|
1926 | RET
|
---|
1927 | SHOW_DATA ENDP
|
---|
1928 |
|
---|
1929 |
|
---|
1930 | ASSUME BP:PTR ISTACKFRAME
|
---|
1931 | REG_DUMP PROC NEAR
|
---|
1932 | MOV AL, "D"
|
---|
1933 | MOV DX, I_DS
|
---|
1934 | CALL RD_SEG
|
---|
1935 | MOV AL, "E"
|
---|
1936 | MOV DX, I_ES
|
---|
1937 | CALL RD_SEG
|
---|
1938 | MOV AL, "F"
|
---|
1939 | MOV DX, I_FS
|
---|
1940 | CALL RD_SEG
|
---|
1941 | MOV AL, "G"
|
---|
1942 | MOV DX, I_GS
|
---|
1943 | CALL RD_SEG
|
---|
1944 | MOV DX, SS
|
---|
1945 | TEST I_CS, 3 ; RPL=0?
|
---|
1946 | JZ SHORT RD_1
|
---|
1947 | MOV DX, I_SS
|
---|
1948 | RD_1: MOV AL, "S"
|
---|
1949 | CALL RD_SEG
|
---|
1950 | MOV AL, " "
|
---|
1951 | CALL GCHAR
|
---|
1952 | LEA BX, FLAG_TAB
|
---|
1953 | MOV EDX, I_EFLAGS
|
---|
1954 | RD_F1: MOV CX, [BX+0]
|
---|
1955 | JCXZ RD_F9
|
---|
1956 | MOV AL, " "
|
---|
1957 | CALL GCHAR
|
---|
1958 | MOV AX, [BX+2]
|
---|
1959 | TEST DX, CX
|
---|
1960 | JZ SHORT RD_F2
|
---|
1961 | MOV AX, [BX+4]
|
---|
1962 | RD_F2: CALL GCHAR
|
---|
1963 | MOV AL, AH
|
---|
1964 | CALL GCHAR
|
---|
1965 | ADD BX, 6
|
---|
1966 | JMP SHORT RD_F1
|
---|
1967 | RD_F9: CALL GCRLF
|
---|
1968 |
|
---|
1969 | MOV BL, "X"
|
---|
1970 | MOV AH, "A"
|
---|
1971 | MOV EDX, I_EAX
|
---|
1972 | CALL RD_GEN
|
---|
1973 | MOV AH, "B"
|
---|
1974 | MOV EDX, I_EBX
|
---|
1975 | CALL RD_GEN
|
---|
1976 | MOV AH, "C"
|
---|
1977 | MOV EDX, I_ECX
|
---|
1978 | CALL RD_GEN
|
---|
1979 | MOV AH, "D"
|
---|
1980 | MOV EDX, I_EDX
|
---|
1981 | CALL RD_GEN
|
---|
1982 | CALL GCRLF
|
---|
1983 | MOV BL, "I"
|
---|
1984 | MOV AH, "S"
|
---|
1985 | MOV EDX, I_ESI
|
---|
1986 | CALL RD_GEN
|
---|
1987 | MOV AH, "D"
|
---|
1988 | MOV EDX, I_EDI
|
---|
1989 | CALL RD_GEN
|
---|
1990 | MOV BL, "P"
|
---|
1991 | MOV AH, "B"
|
---|
1992 | MOV EDX, I_EBP
|
---|
1993 | CALL RD_GEN
|
---|
1994 | LEA EDX, I_ESP
|
---|
1995 | TEST I_CS, 3 ; RPL=0?
|
---|
1996 | JZ SHORT RD_2
|
---|
1997 | MOV EDX, I_ESP
|
---|
1998 | RD_2: MOV AH, "S"
|
---|
1999 | CALL RD_GEN
|
---|
2000 | CALL GCRLF
|
---|
2001 | RET
|
---|
2002 | ASSUME BP:NOTHING
|
---|
2003 | REG_DUMP ENDP
|
---|
2004 |
|
---|
2005 | RD_SEG PROC NEAR
|
---|
2006 | CALL GCHAR
|
---|
2007 | MOV AL, "S"
|
---|
2008 | CALL GCHAR
|
---|
2009 | MOV AL, "="
|
---|
2010 | CALL GCHAR
|
---|
2011 | MOV AX, DX
|
---|
2012 | CALL GWORD
|
---|
2013 | MOV AL, " "
|
---|
2014 | CALL GCHAR
|
---|
2015 | RET
|
---|
2016 | RD_SEG ENDP
|
---|
2017 |
|
---|
2018 | RD_GEN PROC NEAR
|
---|
2019 | MOV AL, "E"
|
---|
2020 | CALL GCHAR
|
---|
2021 | MOV AL, AH
|
---|
2022 | CALL GCHAR
|
---|
2023 | MOV AL, BL
|
---|
2024 | CALL GCHAR
|
---|
2025 | MOV AL, "="
|
---|
2026 | CALL GCHAR
|
---|
2027 | MOV EAX, EDX
|
---|
2028 | CALL GDWORD
|
---|
2029 | MOV AL, " "
|
---|
2030 | CALL GCHAR
|
---|
2031 | RET
|
---|
2032 | RD_GEN ENDP
|
---|
2033 |
|
---|
2034 |
|
---|
2035 | ;
|
---|
2036 | ; In: DI Address of routine to be called
|
---|
2037 | ;
|
---|
2038 | ; Routine pointed to by DI:
|
---|
2039 | ;
|
---|
2040 | ; In: EAX Page table entry
|
---|
2041 | ; EDX Swap table entry
|
---|
2042 | ; ADDR_LIN Linear address
|
---|
2043 | ;
|
---|
2044 | SCAN_PAGE_TABLES PROC NEAR
|
---|
2045 | MOV ADDR_LIN, 0
|
---|
2046 | MOV AX, G_PAGEDIR_SEL
|
---|
2047 | MOV FS, AX
|
---|
2048 | MOV ESI, 0
|
---|
2049 | SPT_10: MOV EBX, FS:[ESI]
|
---|
2050 | TEST BL, PAGE_PRESENT
|
---|
2051 | JZ SHORT SPT_18
|
---|
2052 | MOV EAX, FS:[ESI+4096]
|
---|
2053 | OR EAX, EAX
|
---|
2054 | JZ SHORT SPT_18
|
---|
2055 | PUSH ESI
|
---|
2056 | MOV ESI, EAX
|
---|
2057 | AND EBX, NOT 0FFFH
|
---|
2058 | MOV AX, G_PHYS_SEL
|
---|
2059 | MOV ES, AX
|
---|
2060 | MOV CX, 1024
|
---|
2061 | SPT_11: MOV EAX, ES:[EBX]
|
---|
2062 | MOV EDX, ES:[ESI]
|
---|
2063 | PUSH ES
|
---|
2064 | PUSH FS
|
---|
2065 | PUSH EBX
|
---|
2066 | PUSH ESI
|
---|
2067 | PUSH CX
|
---|
2068 | PUSH DI
|
---|
2069 | CALL DI
|
---|
2070 | POP DI
|
---|
2071 | POP CX
|
---|
2072 | POP ESI
|
---|
2073 | POP EBX
|
---|
2074 | POP FS
|
---|
2075 | POP ES
|
---|
2076 | ADD EBX, 4
|
---|
2077 | ADD ESI, 4
|
---|
2078 | ADD ADDR_LIN, 4096
|
---|
2079 | LOOP SPT_11
|
---|
2080 | POP ESI
|
---|
2081 | JMP SHORT SPT_19
|
---|
2082 |
|
---|
2083 | SPT_18: ADD ADDR_LIN, 1024 * 4096
|
---|
2084 | SPT_19: ADD ESI, 4
|
---|
2085 | CMP ESI, 4096
|
---|
2086 | JB SPT_10
|
---|
2087 | RET
|
---|
2088 | SCAN_PAGE_TABLES ENDP
|
---|
2089 |
|
---|
2090 |
|
---|
2091 | ;
|
---|
2092 | ; Display info about linear address (ADDR_LIN)
|
---|
2093 | ;
|
---|
2094 | SHOW_LIN PROC NEAR
|
---|
2095 | MOV EAX, ADDR_LIN
|
---|
2096 | CALL GDWORD
|
---|
2097 | MOV AL, " "
|
---|
2098 | CALL GCHAR
|
---|
2099 | MOV AX, G_PAGEDIR_SEL
|
---|
2100 | MOV ES, AX
|
---|
2101 | MOV EAX, ADDR_LIN
|
---|
2102 | SHR EAX, 22 ; Compute page directory index
|
---|
2103 | MOV ESI, ES:[4*EAX+0] ; Get page directory entry
|
---|
2104 | MOV EDI, ES:[4*EAX+4096] ; Get swap directory entry
|
---|
2105 | TEST ESI, PAGE_PRESENT ; Page table present?
|
---|
2106 | JNZ SHORT SL_1 ; Yes -> continue
|
---|
2107 | LEA EDX, $PAGE_DIR ; Display message
|
---|
2108 | CALL GTEXT
|
---|
2109 | JMP SL_RET ; Done
|
---|
2110 | SL_1: MOV AX, G_PHYS_SEL
|
---|
2111 | MOV ES, AX
|
---|
2112 | AND ESI, NOT 0FFFH ; Page table address
|
---|
2113 | MOV EAX, ADDR_LIN ; Get linear address
|
---|
2114 | SHR EAX, 12
|
---|
2115 | AND EAX, 03FFH ; Page table index
|
---|
2116 | LEA ESI, [ESI+4*EAX] ; Address of page table entry
|
---|
2117 | OR EDI, EDI
|
---|
2118 | JZ SHORT SL_2
|
---|
2119 | LEA EDI, [EDI+4*EAX] ; Address of swap table entry
|
---|
2120 | SL_2: LEA EDX, $PHYSICAL
|
---|
2121 | CALL GTEXT
|
---|
2122 | MOV EBX, ADDR_LIN
|
---|
2123 | MOV EAX, ES:[ESI]
|
---|
2124 | AND EAX, NOT 0FFFH
|
---|
2125 | AND EBX, 0FFFH
|
---|
2126 | OR EAX, EBX
|
---|
2127 | CALL GDWORD
|
---|
2128 | MOV AL, " "
|
---|
2129 | CALL GCHAR
|
---|
2130 | MOV EBX, ES:[ESI]
|
---|
2131 | MOV AL, "P"
|
---|
2132 | TEST EBX, PAGE_PRESENT
|
---|
2133 | CALL SHOW_BIT
|
---|
2134 | MOV AL, "A"
|
---|
2135 | TEST EBX, PAGE_ACCESSED
|
---|
2136 | CALL SHOW_BIT
|
---|
2137 | MOV AL, "D"
|
---|
2138 | TEST EBX, PAGE_DIRTY
|
---|
2139 | CALL SHOW_BIT
|
---|
2140 | TEST EBX, PAGE_USER
|
---|
2141 | JNZ SHORT SL_P1
|
---|
2142 | MOV AL, "-"
|
---|
2143 | CALL GCHAR
|
---|
2144 | JMP SHORT SL_P2
|
---|
2145 | SL_P1: MOV AL, "W"
|
---|
2146 | TEST EBX, PAGE_WRITE
|
---|
2147 | CALL SHOW_BIT
|
---|
2148 | SL_P2: MOV AL, "L"
|
---|
2149 | TEST EBX, PAGE_LOCKED
|
---|
2150 | CALL SHOW_BIT
|
---|
2151 | MOV AL, "X"
|
---|
2152 | TEST EBX, PAGE_ALLOC
|
---|
2153 | CALL SHOW_BIT
|
---|
2154 | MOV AL, " "
|
---|
2155 | CALL GCHAR
|
---|
2156 | OR EDI, EDI ; Swapper info table present?
|
---|
2157 | JZ SHORT SL_3 ; No -> skip
|
---|
2158 | MOV AL, ES:[EDI] ; Get process index
|
---|
2159 | CALL GBYTE ; Display process index
|
---|
2160 | MOV AL, " "
|
---|
2161 | CALL GCHAR
|
---|
2162 | MOV BX, ES:[EDI]
|
---|
2163 | AND BX, SRC_MASK
|
---|
2164 | MOV AL, "N"
|
---|
2165 | CMP BX, SRC_NONE
|
---|
2166 | JE SHORT SL_SRC
|
---|
2167 | MOV AL, "Z"
|
---|
2168 | CMP BX, SRC_ZERO
|
---|
2169 | JE SHORT SL_SRC
|
---|
2170 | MOV AL, "E"
|
---|
2171 | CMP BX, SRC_EXEC
|
---|
2172 | JE SHORT SL_SRC
|
---|
2173 | MOV AL, "S"
|
---|
2174 | CMP BX, SRC_SWAP
|
---|
2175 | JE SHORT SL_SRC
|
---|
2176 | MOV AL, "?"
|
---|
2177 | SL_SRC: CALL GCHAR
|
---|
2178 | TEST WORD PTR ES:[EDI], SWAP_ALLOC
|
---|
2179 | MOV AL, "X"
|
---|
2180 | CALL SHOW_BIT
|
---|
2181 | JMP SHORT SL_4
|
---|
2182 |
|
---|
2183 | SL_3: MOV AL, " "
|
---|
2184 | CALL GCHAR
|
---|
2185 | CALL GCHAR
|
---|
2186 | CALL GCHAR
|
---|
2187 | CALL GCHAR
|
---|
2188 | CALL GCHAR
|
---|
2189 | SL_4: MOV AL, " "
|
---|
2190 | CALL GCHAR
|
---|
2191 | MOV BX, ES:[EDI] ; Get swapper info table entry
|
---|
2192 | TEST BX, SWAP_ALLOC ; Swap space allocated?
|
---|
2193 | JNZ SL_EXT ; Yes -> show address
|
---|
2194 | AND BX, SRC_MASK ; Extract SRC field
|
---|
2195 | CMP BX, SRC_EXEC ; Load from exec file?
|
---|
2196 | JNE SHORT SL_NS ; No -> don't show address
|
---|
2197 | SL_EXT: LEA EDX, $EXTERNAL
|
---|
2198 | CALL GTEXT
|
---|
2199 | MOV EAX, ES:[EDI]
|
---|
2200 | AND EAX, NOT 0FFFH
|
---|
2201 | CALL GDWORD
|
---|
2202 | MOV AL, " "
|
---|
2203 | CALL GCHAR
|
---|
2204 | SL_NS: CALL GCRLF
|
---|
2205 | SL_RET: RET
|
---|
2206 | SHOW_LIN ENDP
|
---|
2207 |
|
---|
2208 |
|
---|
2209 |
|
---|
2210 | ;
|
---|
2211 | ; Set breakpoint 0 at address DX:EAX
|
---|
2212 | ;
|
---|
2213 | ; In: DX:EAX Address of breakpoint
|
---|
2214 | ;
|
---|
2215 | ; Out: NZ Error
|
---|
2216 | ;
|
---|
2217 | SET_BREAKPOINT PROC NEAR
|
---|
2218 | PUSH EAX
|
---|
2219 | PUSH EBX
|
---|
2220 | VERR DX
|
---|
2221 | JNZ SHORT SB1
|
---|
2222 | MOV BREAKPOINTS[0].BP_TYPE, BP_BREAKPOINT
|
---|
2223 | MOV BREAKPOINTS[0].BP_SEL, DX
|
---|
2224 | MOV BREAKPOINTS[0].BP_OFF, EAX
|
---|
2225 | MOV EBX, EAX
|
---|
2226 | MOV AX, DX
|
---|
2227 | CALL GET_LIN
|
---|
2228 | MOV BREAKPOINTS[0].BP_ADDR, EBX
|
---|
2229 | XOR EAX, EAX
|
---|
2230 | SB1: POP EBX
|
---|
2231 | POP EAX
|
---|
2232 | RET
|
---|
2233 | SET_BREAKPOINT ENDP
|
---|
2234 |
|
---|
2235 |
|
---|
2236 | ;
|
---|
2237 | ; Set watchpoint (or breakpoint)
|
---|
2238 | ;
|
---|
2239 | ; In: DX:EAX Address
|
---|
2240 | ; BL Type (BP_BREAKPOINT, BP_WATCHPOINT_?)
|
---|
2241 | ; BH Length:
|
---|
2242 | ; 0 BYTE
|
---|
2243 | ; 1 WORD
|
---|
2244 | ; 3 DWORD
|
---|
2245 | ;
|
---|
2246 | ; Out: SI Pointer to breakpoint table entry (0 if table full)
|
---|
2247 | ; NZ Error
|
---|
2248 | ;
|
---|
2249 | SET_WATCHPOINT PROC NEAR
|
---|
2250 | PUSH EAX
|
---|
2251 | PUSH CX
|
---|
2252 | VERR DX
|
---|
2253 | JNZ SHORT SET_WP9
|
---|
2254 | LEA SI, BREAKPOINTS
|
---|
2255 | ASSUME SI:PTR BREAKPOINT
|
---|
2256 | MOV CX, 3
|
---|
2257 | SET_WP1: ADD SI, SIZE BREAKPOINT
|
---|
2258 | CMP [SI].BP_TYPE, BP_INACTIVE
|
---|
2259 | JE SHORT SET_WP2
|
---|
2260 | LOOP SET_WP1
|
---|
2261 | XOR SI, SI ; Table full
|
---|
2262 | OR CL, 1 ; Set NZ
|
---|
2263 | JMP SHORT SET_WP9
|
---|
2264 | SET_WP2: PUSH EBX
|
---|
2265 | MOV [SI].BP_TYPE, BL
|
---|
2266 | MOV [SI].BP_LEN, BH
|
---|
2267 | MOV [SI].BP_SEL, DX
|
---|
2268 | MOV [SI].BP_OFF, EAX
|
---|
2269 | MOV EBX, EAX
|
---|
2270 | MOV AX, DX
|
---|
2271 | CALL GET_LIN
|
---|
2272 | MOV [SI].BP_ADDR, EBX
|
---|
2273 | POP EBX
|
---|
2274 | XOR EAX, EAX
|
---|
2275 | SET_WP9: POP CX
|
---|
2276 | POP EAX
|
---|
2277 | RET
|
---|
2278 | ASSUME SI:NOTHING
|
---|
2279 | SET_WATCHPOINT ENDP
|
---|
2280 |
|
---|
2281 |
|
---|
2282 | ;
|
---|
2283 | ; Insert breakpoints
|
---|
2284 | ;
|
---|
2285 | ASSUME BP:PTR ISTACKFRAME
|
---|
2286 | INS_BREAKPOINTS PROC NEAR
|
---|
2287 | PUSH ESI
|
---|
2288 | PUSH EDI
|
---|
2289 | PUSH EBX
|
---|
2290 | CMP DEBUG_FLAG, FALSE
|
---|
2291 | JE SHORT INSBP_0
|
---|
2292 | LEA EDX, $INSBRK
|
---|
2293 | CALL GTEXT
|
---|
2294 | INSBP_0: MOV EDI, 0 ; DR7
|
---|
2295 | LEA SI, BREAKPOINTS
|
---|
2296 | ASSUME SI:PTR BREAKPOINT
|
---|
2297 | MOV DX, 4
|
---|
2298 | MOV CL, 0
|
---|
2299 | INSBP_1: CMP [SI].BP_TYPE, BP_BREAKPOINT ; Code breakpoint?
|
---|
2300 | JNE SHORT INSBP_3 ; No -> inactive or watchpoint
|
---|
2301 | CMP SKIP_FLAG, FALSE ; Skipping breakpoint?
|
---|
2302 | JE SHORT INSBP_2 ; No -> don't check address
|
---|
2303 | MOV EAX, [SI].BP_OFF
|
---|
2304 | CMP EAX, I_EIP ; Breakpoint at CS:EIP?
|
---|
2305 | JNE SHORT INSBP_2 ; No -> set breakpoint
|
---|
2306 | MOV AX, [SI].BP_SEL
|
---|
2307 | CMP AX, I_CS
|
---|
2308 | JE SHORT INSBP_9 ; Yes -> ignore breakpoint
|
---|
2309 | INSBP_2: MOV BL, 0
|
---|
2310 | MOV BH, 00H ; Instruction execution only
|
---|
2311 | JMP SHORT INSBP_5
|
---|
2312 | INSBP_3: MOV BL,[SI].BP_LEN
|
---|
2313 | MOV BH, 03H ; Data reads or writes only
|
---|
2314 | CMP [SI].BP_TYPE, BP_WATCHPOINT_R
|
---|
2315 | JE SHORT INSBP_4
|
---|
2316 | MOV BH, 01H ; Data writes only
|
---|
2317 | CMP [SI].BP_TYPE, BP_WATCHPOINT_W
|
---|
2318 | JE SHORT INSBP_4
|
---|
2319 | CMP [SI].BP_TYPE, BP_WATCHPOINT_X
|
---|
2320 | JNE SHORT INSBP_9
|
---|
2321 | INSBP_4: CALL WATCH_GET
|
---|
2322 | MOV [SI].BP_VAL, EAX
|
---|
2323 | INSBP_5: CMP DEBUG_FLAG, FALSE
|
---|
2324 | JE SHORT INSBP_6
|
---|
2325 | PUSHAD
|
---|
2326 | CALL SHOW_BREAKPOINT
|
---|
2327 | POPAD
|
---|
2328 | INSBP_6: SHL BL, 2
|
---|
2329 | OR BL, BH
|
---|
2330 | MOVZX EAX, BL
|
---|
2331 | SHL EAX, 16
|
---|
2332 | SHL EAX, CL
|
---|
2333 | OR EAX, 01H ; L0
|
---|
2334 | SHL EAX, CL
|
---|
2335 | OR EDI, EAX
|
---|
2336 | OR EDI, 100H ; LE
|
---|
2337 | MOV EAX, [SI].BP_ADDR
|
---|
2338 | CMP DX, 4
|
---|
2339 | JE SHORT INSBP_ADDR_0
|
---|
2340 | CMP DX, 3
|
---|
2341 | JE SHORT INSBP_ADDR_1
|
---|
2342 | CMP DX, 2
|
---|
2343 | JE SHORT INSBP_ADDR_2
|
---|
2344 | INSBP_ADDR_3: MOV DR3, EAX
|
---|
2345 | JMP SHORT INSBP_9
|
---|
2346 | INSBP_ADDR_1: MOV DR1, EAX
|
---|
2347 | JMP SHORT INSBP_9
|
---|
2348 | INSBP_ADDR_2: MOV DR2, EAX
|
---|
2349 | JMP SHORT INSBP_9
|
---|
2350 | INSBP_ADDR_0: MOV DR0, EAX
|
---|
2351 | INSBP_9: ADD SI, SIZE BREAKPOINT
|
---|
2352 | ADD CL, 2
|
---|
2353 | DEC DX
|
---|
2354 | JNZ INSBP_1
|
---|
2355 | ASSUME SI:NOTHING
|
---|
2356 | MOV DR7, EDI
|
---|
2357 | POP EBX
|
---|
2358 | POP EDI
|
---|
2359 | POP ESI
|
---|
2360 | RET
|
---|
2361 | ASSUME BP:NOTHING
|
---|
2362 | INS_BREAKPOINTS ENDP
|
---|
2363 |
|
---|
2364 | ;
|
---|
2365 | ; Read watch area
|
---|
2366 | ;
|
---|
2367 | ; In: DS:SI Pointer to breakpoint table entry
|
---|
2368 | ;
|
---|
2369 | ; Out: EAX Contents
|
---|
2370 | ;
|
---|
2371 | ASSUME SI:PTR BREAKPOINT
|
---|
2372 | WATCH_GET PROC NEAR
|
---|
2373 | PUSH ES
|
---|
2374 | PUSH EDI
|
---|
2375 | MOV ES, [SI].BP_SEL
|
---|
2376 | MOV EDI, [SI].BP_OFF
|
---|
2377 | CMP [SI].BP_LEN, 0
|
---|
2378 | JE SHORT WATCH_GET_1
|
---|
2379 | CMP [SI].BP_LEN, 1
|
---|
2380 | JE SHORT WATCH_GET_2
|
---|
2381 | MOV EAX, ES:[EDI]
|
---|
2382 | WATCH_GET_RET: POP EDI
|
---|
2383 | POP ES
|
---|
2384 | RET
|
---|
2385 | WATCH_GET_1: MOVZX EAX, BYTE PTR ES:[EDI]
|
---|
2386 | JMP SHORT WATCH_GET_RET
|
---|
2387 | WATCH_GET_2: MOVZX EAX, WORD PTR ES:[EDI]
|
---|
2388 | JMP SHORT WATCH_GET_RET
|
---|
2389 | ASSUME SI:NOTHING
|
---|
2390 | WATCH_GET ENDP
|
---|
2391 |
|
---|
2392 |
|
---|
2393 | ;
|
---|
2394 | ; Input command line
|
---|
2395 | ;
|
---|
2396 | ; In: AL First character
|
---|
2397 | ;
|
---|
2398 | ; Out: BX Pointer to first non-blank character (DS=SV_DATA)
|
---|
2399 | ; CY Error (never)
|
---|
2400 | ;
|
---|
2401 | INPUT PROC NEAR
|
---|
2402 | CALL GCHAR
|
---|
2403 | LEA BX, INPUT_BUF
|
---|
2404 | MOV CL, 0
|
---|
2405 | INPUT_LOOP: CALL GINCHAR
|
---|
2406 | CMP AL, " "
|
---|
2407 | JAE SHORT INPUT_PUT
|
---|
2408 | CMP AL, LF
|
---|
2409 | JE SHORT INPUT_END
|
---|
2410 | CMP AL, CR
|
---|
2411 | JE SHORT INPUT_END
|
---|
2412 | CMP AL, 08H ; ^H
|
---|
2413 | JE SHORT INPUT_BACK
|
---|
2414 | CMP AL, 7FH ; DEL
|
---|
2415 | JE SHORT INPUT_BACK
|
---|
2416 | CMP AL, 15H ; ^U
|
---|
2417 | JE SHORT INPUT_KILL
|
---|
2418 | CMP AL, 18H ; ^X
|
---|
2419 | JE SHORT INPUT_KILL
|
---|
2420 | INPUT_BEEP: MOV AL, 07H
|
---|
2421 | CALL GCHAR
|
---|
2422 | JMP SHORT INPUT_LOOP
|
---|
2423 |
|
---|
2424 |
|
---|
2425 | INPUT_PUT: CMP CL, 64
|
---|
2426 | JAE SHORT INPUT_BEEP
|
---|
2427 | MOV [BX], AL
|
---|
2428 | INC BX
|
---|
2429 | INC CL
|
---|
2430 | CALL GCHAR
|
---|
2431 | JMP SHORT INPUT_LOOP
|
---|
2432 |
|
---|
2433 | INPUT_BACK: CMP CL, 0
|
---|
2434 | JE SHORT INPUT_LOOP
|
---|
2435 | CALL INPUT_DEL
|
---|
2436 | JMP SHORT INPUT_LOOP
|
---|
2437 |
|
---|
2438 | INPUT_END: MOV BYTE PTR [BX], 0
|
---|
2439 | CALL GCRLF
|
---|
2440 | LEA BX, INPUT_BUF
|
---|
2441 | CALL SKIP
|
---|
2442 | CLC
|
---|
2443 | RET
|
---|
2444 |
|
---|
2445 | INPUT_KILL: CMP CL, 0
|
---|
2446 | JE SHORT INPUT_LOOP
|
---|
2447 | CALL INPUT_DEL
|
---|
2448 | JMP SHORT INPUT_KILL
|
---|
2449 |
|
---|
2450 | INPUT ENDP
|
---|
2451 |
|
---|
2452 |
|
---|
2453 | INPUT_DEL PROC NEAR
|
---|
2454 | DEC CL
|
---|
2455 | DEC BX
|
---|
2456 | MOV AL, 08H
|
---|
2457 | CALL GCHAR
|
---|
2458 | MOV AL, " "
|
---|
2459 | CALL GCHAR
|
---|
2460 | MOV AL, 08H
|
---|
2461 | CALL GCHAR
|
---|
2462 | RET
|
---|
2463 | INPUT_DEL ENDP
|
---|
2464 |
|
---|
2465 |
|
---|
2466 | ;
|
---|
2467 | ; Fetch next character
|
---|
2468 | ;
|
---|
2469 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2470 | ;
|
---|
2471 | ; Out: AL Character (uppercase)
|
---|
2472 | ; ZR End of line
|
---|
2473 | ; BX Advanced to next character
|
---|
2474 | ;
|
---|
2475 | FETCH PROC NEAR
|
---|
2476 | FETCH1: MOV AL, [BX]
|
---|
2477 | CALL END_OF_LINE
|
---|
2478 | JZ SHORT FETCH9
|
---|
2479 | INC BX
|
---|
2480 | CALL UPPER
|
---|
2481 | OR AL, AL
|
---|
2482 | FETCH9: RET
|
---|
2483 | FETCH ENDP
|
---|
2484 |
|
---|
2485 | ;
|
---|
2486 | ; Skip blanks and TABs
|
---|
2487 | ;
|
---|
2488 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2489 | ;
|
---|
2490 | ; Out: BX Next character
|
---|
2491 | ;
|
---|
2492 | SKIP PROC NEAR
|
---|
2493 | SKIP1: CMP BYTE PTR [BX], " "
|
---|
2494 | JE SHORT SKIP2
|
---|
2495 | CMP BYTE PTR [BX], TAB
|
---|
2496 | JNE SHORT SKIP9
|
---|
2497 | SKIP2: INC BX
|
---|
2498 | JMP SHORT SKIP1
|
---|
2499 | SKIP9: RET
|
---|
2500 | SKIP ENDP
|
---|
2501 |
|
---|
2502 |
|
---|
2503 | ;
|
---|
2504 | ; Check for argument delimiter
|
---|
2505 | ;
|
---|
2506 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2507 | ;
|
---|
2508 | ; Out: ZR Delimiter
|
---|
2509 | ;
|
---|
2510 | DELIM: CMP BYTE PTR [BX], TAB
|
---|
2511 | JE SHORT EOL9
|
---|
2512 | CMP BYTE PTR [BX], " "
|
---|
2513 | JE SHORT EOL9
|
---|
2514 | ;
|
---|
2515 | ; Check for end of line
|
---|
2516 | ;
|
---|
2517 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2518 | ;
|
---|
2519 | ; Out: ZR End of line
|
---|
2520 | ;
|
---|
2521 | END_OF_LINE: CMP BYTE PTR [BX], 00H
|
---|
2522 | JE SHORT EOL9
|
---|
2523 | CMP BYTE PTR [BX], LF
|
---|
2524 | JE SHORT EOL9
|
---|
2525 | CMP BYTE PTR [BX], CR
|
---|
2526 | EOL9: RET
|
---|
2527 |
|
---|
2528 |
|
---|
2529 | ;
|
---|
2530 | ; Parse an address range
|
---|
2531 | ;
|
---|
2532 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2533 | ; DX Default selector
|
---|
2534 | ;
|
---|
2535 | ; Out: CY Error
|
---|
2536 | ; DX Selector
|
---|
2537 | ; EAX Offset
|
---|
2538 | ; ECX Size
|
---|
2539 | ; EDX Error message
|
---|
2540 | ;
|
---|
2541 | GET_RANGE PROC NEAR
|
---|
2542 | CALL GET_ADDR
|
---|
2543 | JC SHORT GRNG_INPUT_ERROR
|
---|
2544 | GET_RANGE_MORE::VERR DX
|
---|
2545 | JNZ SHORT GRNG_INVALID_SEL
|
---|
2546 | MOV RANGE_SEL, DX
|
---|
2547 | MOV RANGE_OFF, EAX
|
---|
2548 | CALL GET_ADDR ; Keep DX
|
---|
2549 | JC SHORT GRNG_INPUT_ERROR
|
---|
2550 | CMP DX, RANGE_SEL
|
---|
2551 | JNE SHORT GRNG_INPUT_ERROR
|
---|
2552 | AND EDX, 0FFFFH
|
---|
2553 | LSL ECX, EDX
|
---|
2554 | CMP EAX, ECX
|
---|
2555 | JA SHORT GRNG_BEYOND_LIMIT
|
---|
2556 | SUB EAX, RANGE_OFF
|
---|
2557 | JB SHORT GRNG_INPUT_ERROR
|
---|
2558 | INC EAX
|
---|
2559 | MOV ECX, EAX
|
---|
2560 | MOV EAX, RANGE_OFF
|
---|
2561 | CLC
|
---|
2562 | RET
|
---|
2563 |
|
---|
2564 | GRNG_BEYOND_LIMIT:
|
---|
2565 | LEA EDX, $BEYOND_LIMIT
|
---|
2566 | JMP SHORT GRNG_ERROR
|
---|
2567 |
|
---|
2568 | GRNG_INVALID_SEL:
|
---|
2569 | LEA EDX, $INVALID_SEL
|
---|
2570 | JMP SHORT GRNG_ERROR
|
---|
2571 |
|
---|
2572 | GRNG_INPUT_ERROR:
|
---|
2573 | LEA EDX, $INPUT_ERROR
|
---|
2574 | GRNG_ERROR: STC
|
---|
2575 | RET
|
---|
2576 | GET_RANGE ENDP
|
---|
2577 |
|
---|
2578 |
|
---|
2579 | ;
|
---|
2580 | ; Parse an address
|
---|
2581 | ;
|
---|
2582 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2583 | ; DX Default selector
|
---|
2584 | ;
|
---|
2585 | ; Out: CY Error
|
---|
2586 | ; DX Selector
|
---|
2587 | ; EAX Offset
|
---|
2588 | ;
|
---|
2589 | GET_ADDR PROC NEAR
|
---|
2590 | PUSH BX
|
---|
2591 | CALL GET_NUMBER
|
---|
2592 | JC SHORT GET_ADDR_1
|
---|
2593 | CMP BYTE PTR [BX], ":"
|
---|
2594 | JNE SHORT GET_ADDR_END
|
---|
2595 | INC BX
|
---|
2596 | MOV DX, AX
|
---|
2597 | CALL GET_NUMBER
|
---|
2598 | JC SHORT GET_ADDR_1
|
---|
2599 | GET_ADDR_END: CALL DELIM
|
---|
2600 | JZ SHORT GET_ADDR_OK
|
---|
2601 | GET_ADDR_1: POP BX
|
---|
2602 | PUSH BX
|
---|
2603 | PUSH DI
|
---|
2604 | LEA DI, SYMBOL_BUF
|
---|
2605 | MOV BYTE PTR [DI], "_"
|
---|
2606 | INC DI
|
---|
2607 | GET_ADDR_S1: MOV AL, [BX]
|
---|
2608 | CMP AL, " "
|
---|
2609 | JE SHORT GET_ADDR_S2
|
---|
2610 | CMP AL, TAB
|
---|
2611 | JE SHORT GET_ADDR_S2
|
---|
2612 | CALL END_OF_LINE
|
---|
2613 | JZ SHORT GET_ADDR_S2
|
---|
2614 | MOV [DI], AL
|
---|
2615 | INC DI
|
---|
2616 | INC BX
|
---|
2617 | JMP SHORT GET_ADDR_S1
|
---|
2618 | GET_ADDR_S2: MOV BYTE PTR [DI], 0
|
---|
2619 | PUSH BX
|
---|
2620 | MOV DI, PROCESS_PTR
|
---|
2621 | LEA BX, SYMBOL_BUF
|
---|
2622 | CALL SYM_BY_NAME
|
---|
2623 | JNC GET_ADDR_S3
|
---|
2624 | POP BX
|
---|
2625 | POP DI
|
---|
2626 | JMP SHORT GET_ADDR_ERROR
|
---|
2627 | GET_ADDR_S3: POP BX
|
---|
2628 | POP DI
|
---|
2629 | PUSH EAX
|
---|
2630 | CALL DELIM
|
---|
2631 | POP EAX
|
---|
2632 | JNZ SHORT GET_ADDR_ERROR
|
---|
2633 | XCHG EAX, EDX
|
---|
2634 | CMP DL, SYM_TEXT
|
---|
2635 | MOV DX, L_CODE_SEL
|
---|
2636 | JE SHORT GET_ADDR_OK
|
---|
2637 | MOV DX, L_DATA_SEL
|
---|
2638 | GET_ADDR_OK: CALL SKIP
|
---|
2639 | CLC
|
---|
2640 | JMP SHORT GET_ADDR_RET
|
---|
2641 | GET_ADDR_ERROR: STC
|
---|
2642 | GET_ADDR_RET: ADD ESP, 2 ; Remove BX
|
---|
2643 | RET
|
---|
2644 | GET_ADDR ENDP
|
---|
2645 |
|
---|
2646 | ;
|
---|
2647 | ; Parse a value (number or register or character constant)
|
---|
2648 | ;
|
---|
2649 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2650 | ;
|
---|
2651 | ; Out: CY Error
|
---|
2652 | ; BX Points to next character
|
---|
2653 | ; EAX Value
|
---|
2654 | ;
|
---|
2655 | GET_NUMBER PROC NEAR
|
---|
2656 | PUSH EDX
|
---|
2657 | PUSH CX
|
---|
2658 | CMP BYTE PTR [BX], "'"
|
---|
2659 | JE SHORT GNUM_CHR
|
---|
2660 | CALL GET_REG
|
---|
2661 | JNC SHORT GNUM_REG
|
---|
2662 | GNUM0: XOR EDX, EDX
|
---|
2663 | MOV CX, 0
|
---|
2664 | GNUM1: MOVZX EAX, BYTE PTR [BX]
|
---|
2665 | SUB AL, "0"
|
---|
2666 | JB SHORT GNUM_END
|
---|
2667 | CMP AL, 10
|
---|
2668 | JB SHORT GNUM2
|
---|
2669 | ADD AL, "0"-"A"+10
|
---|
2670 | CMP AL, 10
|
---|
2671 | JB SHORT GNUM_END
|
---|
2672 | CMP AL, 16
|
---|
2673 | JB SHORT GNUM2
|
---|
2674 | ADD AL, "A"-"a"
|
---|
2675 | CMP AL, 10
|
---|
2676 | JB SHORT GNUM_END
|
---|
2677 | CMP AL, 16
|
---|
2678 | JAE SHORT GNUM_END
|
---|
2679 | GNUM2: SHL EDX, 4
|
---|
2680 | ADD EDX, EAX
|
---|
2681 | INC BX
|
---|
2682 | INC CX
|
---|
2683 | JMP SHORT GNUM1
|
---|
2684 | GNUM_END: JCXZ GNUM_ERROR
|
---|
2685 | MOV EAX, EDX
|
---|
2686 | GNUM_OK: CLC
|
---|
2687 | JMP SHORT GNUM_RET
|
---|
2688 |
|
---|
2689 | GNUM_REG: XCHG BX, DX
|
---|
2690 | CMP AL, R8
|
---|
2691 | JE SHORT GNUM_REG_R8
|
---|
2692 | CMP AL, R16
|
---|
2693 | JE SHORT GNUM_REG_R16
|
---|
2694 | GNUM_REG_R32: MOV EAX, SS:[BX]
|
---|
2695 | JMP SHORT GNUM_REG2
|
---|
2696 | GNUM_REG_R16: MOVZX EAX, WORD PTR SS:[BX]
|
---|
2697 | JMP SHORT GNUM_REG2
|
---|
2698 | GNUM_REG_R8: MOVZX EAX, BYTE PTR SS:[BX]
|
---|
2699 | GNUM_REG2: XCHG BX, DX
|
---|
2700 | JMP SHORT GNUM_OK
|
---|
2701 |
|
---|
2702 | GNUM_CHR: INC BX
|
---|
2703 | CALL END_OF_LINE
|
---|
2704 | JZ SHORT GNUM_ERROR
|
---|
2705 | MOVZX EAX, BYTE PTR [BX]
|
---|
2706 | INC BX
|
---|
2707 | CMP BYTE PTR [BX], "'"
|
---|
2708 | JNZ SHORT GNUM_ERROR
|
---|
2709 | INC BX
|
---|
2710 | JMP SHORT GNUM_RET
|
---|
2711 |
|
---|
2712 | GNUM_ERROR: STC
|
---|
2713 | GNUM_RET: POP CX
|
---|
2714 | POP EDX
|
---|
2715 | RET
|
---|
2716 | GET_NUMBER ENDP
|
---|
2717 |
|
---|
2718 | ;
|
---|
2719 | ; Parse a register name
|
---|
2720 | ;
|
---|
2721 | ; In: BX Pointer to input (DS=SV_DATA)
|
---|
2722 | ;
|
---|
2723 | ; Out: CY Error
|
---|
2724 | ; DX Pointer to register (offset into stack segment; SS:DX)
|
---|
2725 | ; AX Register size (R8, R16, R32)
|
---|
2726 | ;
|
---|
2727 | ASSUME BP:PTR ISTACKFRAME
|
---|
2728 | GET_REG PROC NEAR
|
---|
2729 | PUSH SI
|
---|
2730 | PUSH DI
|
---|
2731 | MOV DI, BX
|
---|
2732 | LEA SI, REG_TAB
|
---|
2733 | CLD
|
---|
2734 | GREG1: LODS REG_TAB
|
---|
2735 | CMP AL, 0FFH
|
---|
2736 | JE SHORT GREG_LOSE
|
---|
2737 | CMP AL, R32
|
---|
2738 | JBE SHORT GREG10
|
---|
2739 | MOV AH, AL
|
---|
2740 | CALL FETCH
|
---|
2741 | CMP AL, AH
|
---|
2742 | JE SHORT GREG1
|
---|
2743 | GREG2: LODS REG_TAB
|
---|
2744 | CMP AL, R32
|
---|
2745 | JA SHORT GREG2
|
---|
2746 | GREG3: INC SI
|
---|
2747 | MOV BX, DI
|
---|
2748 | JMP SHORT GREG1
|
---|
2749 |
|
---|
2750 | GREG10: MOVZX DX, BYTE PTR [SI]
|
---|
2751 | CMP DX, 56 ; ESP, SS
|
---|
2752 | JB SHORT GREG11
|
---|
2753 | TEST I_CS, 3 ; RPL=0?
|
---|
2754 | JZ SHORT GREG3
|
---|
2755 | GREG11: ADD DX, BP
|
---|
2756 | XOR AH, AH
|
---|
2757 | JMP SHORT GREG_RET
|
---|
2758 |
|
---|
2759 | GREG_LOSE: MOV BX, DI
|
---|
2760 | STC
|
---|
2761 | GREG_RET: POP DI
|
---|
2762 | POP SI
|
---|
2763 | RET
|
---|
2764 | ASSUME BP:NOTHING
|
---|
2765 | GET_REG ENDP
|
---|
2766 |
|
---|
2767 |
|
---|
2768 | ;
|
---|
2769 | ; Display a number in decimal notation
|
---|
2770 | ;
|
---|
2771 | ; In: EAX Number
|
---|
2772 | ;
|
---|
2773 | DECIMAL PROC NEAR
|
---|
2774 | PUSH EDX
|
---|
2775 | PUSH ECX
|
---|
2776 | CALL DECIMAL2
|
---|
2777 | POP ECX
|
---|
2778 | POP EDX
|
---|
2779 | RET
|
---|
2780 |
|
---|
2781 | DECIMAL1: OR EAX, EAX
|
---|
2782 | JZ SHORT DECIMAL9
|
---|
2783 | DECIMAL2: XOR EDX, EDX
|
---|
2784 | MOV ECX, 10
|
---|
2785 | DIV ECX
|
---|
2786 | PUSH EDX
|
---|
2787 | CALL DECIMAL1
|
---|
2788 | POP EAX
|
---|
2789 | ADD AL, "0"
|
---|
2790 | CALL GCHAR
|
---|
2791 | DECIMAL9: RET
|
---|
2792 | DECIMAL ENDP
|
---|
2793 |
|
---|
2794 |
|
---|
2795 | ASSUME DS:SV_DATA
|
---|
2796 | DEBUG_INIT PROC NEAR
|
---|
2797 | CMP DEBUG_SER_FLAG, FALSE
|
---|
2798 | JE SHORT DEBUG_INIT_RET
|
---|
2799 | MOV GDWORD, OFFSET SV_CODE:S_DWORD
|
---|
2800 | MOV GWORD, OFFSET SV_CODE:S_WORD
|
---|
2801 | MOV GBYTE, OFFSET SV_CODE:S_BYTE
|
---|
2802 | MOV GTEXT, OFFSET SV_CODE:S_TEXT
|
---|
2803 | MOV GCRLF, OFFSET SV_CODE:S_CRLF
|
---|
2804 | MOV GCHAR, OFFSET SV_CODE:S_CHAR
|
---|
2805 | MOV GINCHAR, OFFSET SV_CODE:S_INCHAR
|
---|
2806 | DEBUG_INIT_RET: RET
|
---|
2807 | DEBUG_INIT ENDP
|
---|
2808 |
|
---|
2809 |
|
---|
2810 | ASSUME DS:SV_DATA
|
---|
2811 | DEBUG_QUIT PROC NEAR
|
---|
2812 | CMP STEP_FLAG, FALSE
|
---|
2813 | JE SHORT DQ_RET
|
---|
2814 | LEA EDX, $SWAP_FAULTS
|
---|
2815 | CALL GTEXT
|
---|
2816 | MOV EAX, SWAP_FAULTS
|
---|
2817 | CALL DECIMAL
|
---|
2818 | LEA EDX, $SWAP_READS
|
---|
2819 | CALL GTEXT
|
---|
2820 | MOV EAX, SWAP_READS
|
---|
2821 | CALL DECIMAL
|
---|
2822 | LEA EDX, $SWAP_WRITES
|
---|
2823 | CALL GTEXT
|
---|
2824 | MOV EAX, SWAP_WRITES
|
---|
2825 | CALL DECIMAL
|
---|
2826 | LEA EDX, $SNATCH_COUNT
|
---|
2827 | CALL GTEXT
|
---|
2828 | MOV EAX, SNATCH_COUNT
|
---|
2829 | CALL DECIMAL
|
---|
2830 | LEA EDX, $SWAP_SIZE
|
---|
2831 | CALL GTEXT
|
---|
2832 | MOV EAX, SWAP_SIZE
|
---|
2833 | CALL DECIMAL
|
---|
2834 | CALL GCRLF
|
---|
2835 | CALL CHECK_HANDLES
|
---|
2836 | DQ_RET: RET
|
---|
2837 | DEBUG_QUIT ENDP
|
---|
2838 |
|
---|
2839 |
|
---|
2840 | ASSUME DS:SV_DATA
|
---|
2841 | B_DWORD PROC NEAR
|
---|
2842 | ROR EAX, 16
|
---|
2843 | CALL B_WORD
|
---|
2844 | ROR EAX, 16
|
---|
2845 | CALL B_WORD
|
---|
2846 | RET
|
---|
2847 | B_DWORD ENDP
|
---|
2848 |
|
---|
2849 | ASSUME DS:SV_DATA
|
---|
2850 | B_WORD PROC NEAR
|
---|
2851 | XCHG AL, AH
|
---|
2852 | CALL B_BYTE
|
---|
2853 | XCHG AL, AH
|
---|
2854 | CALL B_BYTE
|
---|
2855 | RET
|
---|
2856 | B_WORD ENDP
|
---|
2857 |
|
---|
2858 |
|
---|
2859 | ASSUME DS:SV_DATA
|
---|
2860 | B_BYTE PROC NEAR
|
---|
2861 | PUSH AX
|
---|
2862 | SHR AL, 4
|
---|
2863 | CALL B_NIBBLE
|
---|
2864 | POP AX
|
---|
2865 | PUSH AX
|
---|
2866 | CALL B_NIBBLE
|
---|
2867 | POP AX
|
---|
2868 | RET
|
---|
2869 | B_BYTE ENDP
|
---|
2870 |
|
---|
2871 | ASSUME DS:SV_DATA
|
---|
2872 | B_NIBBLE PROC NEAR
|
---|
2873 | AND AL, 0FH
|
---|
2874 | ADD AL, 30H
|
---|
2875 | CMP AL, 3AH
|
---|
2876 | JB SHORT SNIB1
|
---|
2877 | ADD AL, 7
|
---|
2878 | SNIB1: CALL B_CHAR
|
---|
2879 | RET
|
---|
2880 | B_NIBBLE ENDP
|
---|
2881 |
|
---|
2882 |
|
---|
2883 | ASSUME DS:SV_DATA
|
---|
2884 | B_TEXT PROC NEAR
|
---|
2885 | PUSH AX
|
---|
2886 | B_TEXT1: MOV AL, DS:[EDX]
|
---|
2887 | CMP AL, 0
|
---|
2888 | JE SHORT B_TEXT9
|
---|
2889 | CALL B_CHAR
|
---|
2890 | INC EDX
|
---|
2891 | JMP SHORT B_TEXT1
|
---|
2892 | B_TEXT9: POP AX
|
---|
2893 | RET
|
---|
2894 | B_TEXT ENDP
|
---|
2895 |
|
---|
2896 | ASSUME DS:SV_DATA
|
---|
2897 | B_CHAR PROC NEAR
|
---|
2898 | PUSH AX
|
---|
2899 | PUSH BX
|
---|
2900 | CMP AL, TAB
|
---|
2901 | JE SHORT BC_TAB
|
---|
2902 | INC B_COLUMN
|
---|
2903 | CMP AL, CR
|
---|
2904 | JNE SHORT BC_1
|
---|
2905 | MOV B_COLUMN, 0
|
---|
2906 | BC_1: MOV BX, 0007H
|
---|
2907 | MOV AH, 0EH
|
---|
2908 | INT 10H
|
---|
2909 | BC_RET: POP BX
|
---|
2910 | POP AX
|
---|
2911 | RET
|
---|
2912 |
|
---|
2913 | BC_TAB: MOV AH, B_COLUMN
|
---|
2914 | NOT AH
|
---|
2915 | AND AH, 7
|
---|
2916 | INC AH
|
---|
2917 | MOV AL, " "
|
---|
2918 | BC_TAB_1: CALL B_CHAR
|
---|
2919 | DEC AH
|
---|
2920 | JNZ SHORT BC_TAB_1
|
---|
2921 | JMP SHORT BC_RET
|
---|
2922 | B_CHAR ENDP
|
---|
2923 |
|
---|
2924 | ASSUME DS:SV_DATA
|
---|
2925 | B_CRLF PROC NEAR
|
---|
2926 | PUSH AX
|
---|
2927 | MOV AL, CR
|
---|
2928 | CALL B_CHAR
|
---|
2929 | MOV AL, LF
|
---|
2930 | CALL B_CHAR
|
---|
2931 | POP AX
|
---|
2932 | RET
|
---|
2933 | B_CRLF ENDP
|
---|
2934 |
|
---|
2935 | ASSUME DS:SV_DATA
|
---|
2936 | B_INCHAR PROC NEAR
|
---|
2937 | XOR AL, AL
|
---|
2938 | XCHG AL, B_NEXT
|
---|
2939 | TEST AL, AL
|
---|
2940 | JNZ SHORT B_INCHAR_RET
|
---|
2941 | B_INCHAR_LOOP: MOV AH, 0
|
---|
2942 | INT 16H
|
---|
2943 | TEST AL, AL
|
---|
2944 | JNZ SHORT B_INCHAR_RET
|
---|
2945 | TEST AH, AH
|
---|
2946 | JZ SHORT B_INCHAR_LOOP
|
---|
2947 | MOV B_NEXT, AH
|
---|
2948 | B_INCHAR_RET: RET
|
---|
2949 | B_INCHAR ENDP
|
---|
2950 |
|
---|
2951 | ASSUME DS:SV_DATA
|
---|
2952 | S_DWORD PROC NEAR
|
---|
2953 | ROR EAX, 16
|
---|
2954 | CALL S_WORD
|
---|
2955 | ROR EAX, 16
|
---|
2956 | CALL S_WORD
|
---|
2957 | RET
|
---|
2958 | S_DWORD ENDP
|
---|
2959 |
|
---|
2960 | ASSUME DS:SV_DATA
|
---|
2961 | S_WORD PROC NEAR
|
---|
2962 | XCHG AL, AH
|
---|
2963 | CALL S_BYTE
|
---|
2964 | XCHG AL, AH
|
---|
2965 | CALL S_BYTE
|
---|
2966 | RET
|
---|
2967 | S_WORD ENDP
|
---|
2968 |
|
---|
2969 |
|
---|
2970 | ASSUME DS:SV_DATA
|
---|
2971 | S_BYTE PROC NEAR
|
---|
2972 | PUSH AX
|
---|
2973 | SHR AL, 4
|
---|
2974 | CALL S_NIBBLE
|
---|
2975 | POP AX
|
---|
2976 | PUSH AX
|
---|
2977 | CALL S_NIBBLE
|
---|
2978 | POP AX
|
---|
2979 | RET
|
---|
2980 | S_BYTE ENDP
|
---|
2981 |
|
---|
2982 | ASSUME DS:SV_DATA
|
---|
2983 | S_NIBBLE PROC NEAR
|
---|
2984 | AND AL, 0FH
|
---|
2985 | ADD AL, 30H
|
---|
2986 | CMP AL, 3AH
|
---|
2987 | JB SHORT SNIB1
|
---|
2988 | ADD AL, 7
|
---|
2989 | SNIB1: CALL S_CHAR
|
---|
2990 | RET
|
---|
2991 | S_NIBBLE ENDP
|
---|
2992 |
|
---|
2993 |
|
---|
2994 | ASSUME DS:SV_DATA
|
---|
2995 | S_TEXT PROC NEAR
|
---|
2996 | PUSH AX
|
---|
2997 | S_TEXT1: MOV AL, DS:[EDX]
|
---|
2998 | CMP AL, 0
|
---|
2999 | JE SHORT S_TEXT9
|
---|
3000 | CALL S_CHAR
|
---|
3001 | INC EDX
|
---|
3002 | JMP SHORT S_TEXT1
|
---|
3003 | S_TEXT9: POP AX
|
---|
3004 | RET
|
---|
3005 | S_TEXT ENDP
|
---|
3006 |
|
---|
3007 | ASSUME DS:SV_DATA
|
---|
3008 | S_CHAR PROC NEAR
|
---|
3009 | PUSH AX
|
---|
3010 | PUSH DX
|
---|
3011 | MOV AH, AL
|
---|
3012 | S_CHAR0: MOV DX, DEBUG_SER_PORT
|
---|
3013 | ADD DX, 4
|
---|
3014 | MOV AL, 3
|
---|
3015 | OUT DX, AL
|
---|
3016 | INC DX
|
---|
3017 | S_CHAR1: IN AL, DX ; Read line status
|
---|
3018 | TEST AL, 01H ; Input character ready?
|
---|
3019 | JZ SHORT S_CHAR2 ; No -> check for output
|
---|
3020 | SUB DX, 5 ; Receiver register
|
---|
3021 | IN AL, DX ; Read input character
|
---|
3022 | CMP AL, 13H ; ^S (XOFF)?
|
---|
3023 | JE SHORT S_CHAR_XOFF ; Yes -> stop
|
---|
3024 | CMP AL, 11H ; ^Q (XON)?
|
---|
3025 | JE SHORT S_CHAR_XON ; Yes -> continue
|
---|
3026 | CMP LOOK_AHEAD, 0 ; Input buffer full?
|
---|
3027 | JNE SHORT S_CHAR0 ; Yes -> discard, repeat
|
---|
3028 | MOV LOOK_AHEAD, AL ; Save input character
|
---|
3029 | JMP SHORT S_CHAR0 ; (if non-zero)
|
---|
3030 |
|
---|
3031 | S_CHAR2: TEST AL, 20H ; Transmitter empty?
|
---|
3032 | JZ SHORT S_CHAR1 ; No -> repeat
|
---|
3033 | CMP XOFF, FALSE ; Stopped?
|
---|
3034 | JNE SHORT S_CHAR1 ; Yes -> repeat
|
---|
3035 | SUB DX, 5 ; Transmitter register
|
---|
3036 | MOV AL, AH ; Write character
|
---|
3037 | OUT DX, AL ; to transmitter register
|
---|
3038 | POP DX
|
---|
3039 | POP AX
|
---|
3040 | RET
|
---|
3041 |
|
---|
3042 | S_CHAR_XON: MOV XOFF, FALSE
|
---|
3043 | JMP SHORT S_CHAR1
|
---|
3044 |
|
---|
3045 | S_CHAR_XOFF: MOV XOFF, NOT FALSE
|
---|
3046 | JMP SHORT S_CHAR1
|
---|
3047 |
|
---|
3048 | S_CHAR ENDP
|
---|
3049 |
|
---|
3050 | ASSUME DS:SV_DATA
|
---|
3051 | S_CRLF PROC NEAR
|
---|
3052 | PUSH AX
|
---|
3053 | MOV AL, CR
|
---|
3054 | CALL S_CHAR
|
---|
3055 | MOV AL, LF
|
---|
3056 | CALL S_CHAR
|
---|
3057 | POP AX
|
---|
3058 | RET
|
---|
3059 | S_CRLF ENDP
|
---|
3060 |
|
---|
3061 |
|
---|
3062 | ASSUME DS:SV_DATA
|
---|
3063 | S_INCHAR PROC NEAR
|
---|
3064 | PUSH DX
|
---|
3065 | XOR AL, AL
|
---|
3066 | XCHG AL, LOOK_AHEAD ; Examine input buffer
|
---|
3067 | OR AL, AL ; Non-empty?
|
---|
3068 | JNZ SHORT S_INCHAR_RET ; Yes -> use buffered character
|
---|
3069 | S_INCHAR1: MOV DX, DEBUG_SER_PORT
|
---|
3070 | ADD DX, 4
|
---|
3071 | MOV AL, 3
|
---|
3072 | OUT DX, AL
|
---|
3073 | INC DX ; Line status register
|
---|
3074 | S_INCHAR2: IN AL, DX ; Read line status
|
---|
3075 | TEST AL, 01H ; Input character ready?
|
---|
3076 | JZ SHORT S_INCHAR2 ; No -> repeat
|
---|
3077 | SUB DX, 5 ; Receiver register
|
---|
3078 | IN AL, DX ; Read input character
|
---|
3079 | OR AL, AL ; NUL?
|
---|
3080 | JZ SHORT S_INCHAR2 ; Yes -> discard, repeat
|
---|
3081 | CMP AL, 13H ; ^S (XOFF)?
|
---|
3082 | JE SHORT S_INCHAR_XOFF ; Yes -> stop
|
---|
3083 | CMP AL, 11H ; ^Q (XON)?
|
---|
3084 | JE SHORT S_INCHAR_XON ; Yes -> continue
|
---|
3085 | S_INCHAR_RET: POP DX
|
---|
3086 | RET
|
---|
3087 |
|
---|
3088 | S_INCHAR_XON: MOV XOFF, FALSE
|
---|
3089 | JMP SHORT S_INCHAR1
|
---|
3090 |
|
---|
3091 | S_INCHAR_XOFF: MOV XOFF, NOT FALSE
|
---|
3092 | JMP SHORT S_INCHAR1
|
---|
3093 |
|
---|
3094 |
|
---|
3095 | S_INCHAR ENDP
|
---|
3096 |
|
---|
3097 |
|
---|
3098 |
|
---|
3099 | SV_CODE ENDS
|
---|
3100 |
|
---|
3101 | END
|
---|