You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

35KB

Developing Your Own 32-Bit Operating System — Chapter-23: Debugger Code

  • Source: /library/Developing Your Own 32-Bit Operating System/source-file.pdf
  • PDF pages: 493–518
  • Pages without text: 493

23 Debugger Code

I
472 Part PV ■ The Operating System Source Code The debugger initially began as a crude memory dumper built into the operating system. It has grown substantially, but is still very immature. While I wrote the operating system, small pieces of the debugger were added as they were needed. The debugger is a separate task, but it is not entered directly from the breakpoint address as an interrupt task. Breakpoints, which are all debug exceptions, are set up to execute an interrupt procedure that does some rather tricky manipulation of the debugger task state segment (TSS). The two major things that are changed are the pointer to the JCB and the CR3 register in the debugger's TSS. They are made to match those of the interrupted task. This allows the debugger to operate in the memory context of the task that was interrupted. Debugger Interrupt Procedure This code excerpt is taken from the file EXCEPT.ASM, which contains handlers for all system exceptions. You will note that even though the two exception procedures are the same, I have left them as individual procedures. I did this because on occasion I had to modify one indi- vidually, and I ended up duplicating them several times after combining them. See Listing 23.1 . Listing 23.1. Exception handlers for entering the debugger. ;===================== Debugger Single Step (Int 1) =============== PUBLIC IntDbgSS: POP dbgOldEIP ; Get EIP of offender for debugger POP dbgOldCS ; POP dbgOldEFlgs ; JMP EnterDebug ; Enter debugger ;===================== Debugger Entry (Int 3) ===================== PUBLIC IntDebug: POP dbgOldEIP ; Get EIP of offender for debugger POP dbgOldCS ; Get CS POP dbgOldEFlgs ; Get Flags JMP EnterDebug ; Enter debugger EnterDebug This piece of code sets up to enter the debugger. If we get here, one of the exceptions has activated and has done a little work based on which exception it was, then it jumped here to enter the debugger. This code effectively replaces the interrupted task with the debugger task (without going through the kernel). First we copy the Page Dir entry from the current job into the debuggers job, then copy the CR3 register from the current TSS into the debugger’ s TSS. This makes the

Chapter 23 ■ Debugger Code |
473 debugger operate in the current task's memory space. All of the debugger’; code and data are in OS protected pages (which are shared with all tasks), so this is OK to do even if the offending task referenced a bogus address. Next, we save the current pRunTSS and place the debugger's TSS in pRunTSS, then jump to the debugger's selector. This switches tasks. EnterDebug: PUSH EAX PUSH EBX PUSH EDX MOV EAX, pRunTSS MOV EBX, [EAX+TSS_CR3] MOV EDX, OFFSET DbgTSS MOV [EDX+TSS_CR3], EBX MOV EAX, [EAX+TSS_pJCB] MOV EDX, [EDX+TSS_pJCB] MOV EBX, [EAX+JcbPD] MOV [EDX+JcbPD], EBX MOV EAX, pRunTSS MOV DbgpTSSSave, EAX MOV EAX, OFFSET DbgTSS MOV pRunTSS, EAX MOV BX, [EAX+Tid] MOV TSS_Sel, BX POP EDX POP EBX POP EAX ;we MUST save caller's registers ; and restore them before the ; task switch into the debugger ;pRunTSS -> EAX ;current CR3 -> EBX ;pDebuggerTSS -> EDX ;CR3 -> DebuggerTSS ;pCrntJCB -> EAX ;pDebuggerJCB -> EDX ;CrntJob Page Dir -> EBX ;Page Dir -> Debugger JCB iSave the current pRunTSS ;Install Debugger's as current ;Set Dbgr as running task ;Set up debugger selector ;make his registers right! JMP FWORD PTR [TSS] ;Switch tasks to debugger ;When the debugger exits, we come here Put the stack back the way it was PUSH dbgOldEFlgs PUSH dbgOldCS PUSH dbgOldEIP IRETD Go back to the caller Debugger Source Listing Listing 23.2 presents the debugger code in its entirety, with the exception of the disassembler. You'll see that much of it is display “grunt work.” The debugger also has its own read-keyboard call in the keyboard service to allow debugging of portions of the keyboard code.

474 Part PV The Operating System Source Code Listing 23.2. Debugger data and code. .DATA .INCLUDE MOSEDF.INC .INCLUDE TSS.INC .INCLUDE RQB.INC .INCLUDE JOB. INC .ALIGN DWORD ; External near Variables EXTRN rgTmrBlks DD EXTRN pJCBs DD EXTRN RdyQ DD EXTRN rgPAM DB ;debugger variables and buffers PUBLIC DbgpTSSSave DD 0 PUBLIC dbgFAULT DD 0FFh PUBLIC dbgFltErc DD 0 PUBLIC dbgOldEIP DD 0 PUBLIC dbgOldCS DD 0 PUBLIC dbgOldEflgs DD 0 DbgVidSave DD 0 dbgBuf DB ‘00000000’ dbgBuf2 DB ‘0000000000’ .ALIGN DWORD cbBufLen2 DD 0 dbgKeyCode DD 0 NextEIP DD 0 dbgGPddl DD 0 dbgGPdd2 DD 0 dbgGPdd3 DD 0 dbgGPdd4 DD 0 dbgGPddS DD 0 dbgGPdd6 DD 0 dbgNextAdd DD 0 dbgCrntAdd DD 0 dbgDumpAdd DD 0 dbgX DD 0 dbgY DD 0 dbgBPAdd DD 0 dbgfDumpD DB 0 fDbglnit DB 0 dbgCRLF DB 0Dh, 0Ah dbgChar DB 0 ;TO save the TSS we interrupted ;0FFh is NO FAULT ;To save interrupted video user [General use buffers Active bytes in buf2 For ReadDbgKbd For Disassem display (next ins to be executed) General purpose DDs (used all over) flag 1 = Msg, 0 Exch ;Address we are setting as next ;Address of instructions we are displaying ;Address we are dumping ;For line and column display coordination ;Crnt Breakpoint Linear addresses ; Boolean- are we dumping DWORDS? ;Has Dbg Video been initialized? dbgMenu ;CR LF for Dump etc. . . DB SStep’ ,0B3h, SetBP’ ,0B3h, ClrBP’ ,0B3h, CS:EIP

Chapter 23 U Debugger Code 475 DB DB dbgSpace DB dbgCont DB dbgClear DB dbgAsterisk DB 42 Exchs’ ,0B3h, ‘Tasks’ ,0B3h, DumpB ' , 0B3h , ' DumpD ' , 0B3h , ENTER to continue, ESC to quit. ,0B3h, ‘CrntAddr’ ,0B3h, ‘Addlnfo ' ;40 bytes ; 01 2345678901 2345678901 2345678901 2345678901 2345678901 234 dbgExchMsg DB ‘Exch Owner dMsgLo dMsgHi Task’ ; 01 2345678901 2345678901 2345678901 2345678901 2345678901 234 dbgTaskMsg DB ‘Task# Job pJCB pTSS Priority ;For Debugger entry conditions dbgFltMsg D3 ‘FATAL Processor Exception/Fault: ' sdbgFltMsg DD $- dbgFltMsg ;Register display text dbgTxt00 dbgTxt0l dbgTxt02 dbgTxt03 dbgTxt04 dbgTxt05 dbgTxt06 dbgTxt07 dbgTxt08 dbgTxt09 dbgTxtl0 dbgTxtn dbgTxtl2 dbgTxt13 dbgTxtU dbgTxt15 dbgTxtl6 dbgTxt17 dbgTxt18 dbgTxt19 dbgTxt20 DB 0B3h, TSS: DB 0B3h, EAX: DB 0B3h, EBX: DB 0B3h, ECX: DB 0B3h, EDX: DB 0B3h, ESI: DB 0B3h, EDI: DB 0B3h, EBP: DB 0B3h, SS: DB 0B3h, ESP: DB 0B3h, CS: DB 0B3h, EIP: DB 0B3h, DS: DB 0B3h, ES: DB 0B3h, FS: DB 0B3h, GS: DB 0B3h, EFL: DB 0B3h, CR0: DB 0B3h, CR2: DB 0B3h, CR3: DB 0B3h, Ere: dbgTxtAddr DB ‘Linear address: ' ;For Important Address Info Display dbgM0 DB •IDT: dbgMl DB ‘GDT: dbgM2 DB ‘RQBs: dbgM3 DB ‘TSS1: dbgM4 DB ‘TSS3: dbgM5 DB ‘LBs: dbgM6 DB ‘RdyQ: dbgM7 DB ‘JCBs: dbgM8 DB ‘SVCs: dbgM9 DB ‘Exch: dbgPA DB ‘PAM: dbgMB DB ‘aTmr:

A-is Part TV ■ The Operating System Source Code Listing 23.2. continued End Data, Begin Code .CODE EXTRN DDtoHex NEAR EXTRN HexToDD NEAR EXTRN _disassemble NEAR EXTRN ReadDbgKbd NEAR PUBLIC DbgTask: MOV EAX, OFFSET DbgVidSave ;Save number of vid we interrupted PUSH EAX CALL FWORD PTR _GetVidOwner STI PUSH 2 CALL FWORD PTR _SetVidOwner ;Dbgr is Job 2 CMP fDbglnit, 0 JNE DbglnitDone CALL FWORD PTR _ClrScr MOV fDbglnit, 1 DbglnitDone: MOV EAX, DbgpTSSSave ;When a fault or debug exception occurs, the values of ;the Instruction Pointer, Code Seg, and flags are not the ;way they were when the exception fired off because of the ; interrupt procedure they entered to get to the debugger. ;We make them the same by putting the values we got from ;the stack (entering the debugger) into the caller's TSS. MOV EBX.dbgOldEflgs ;Store correct flags MOV [EAX+TSS_EFlags] ,EBX ;EAX still has DbgpTSSSave MOV EBX.dbgOldCS ; Store correct CS MOV [EAX+TSS_CS] , BX MOV EBX.dbgOldEIP ;Store correct EIP MOV [EAX+TSS_EIP],EBX NOTE: The “book” says the TF flag is reset by the processor when the handler is entered. This only applies if the handler is a procedure (NOT a task). The debugger is always entered as a procedure, (we change the tasks) so we shouldn't have to reset it. But we do... I guess I'm not reading it right or ROD SERLING LIVES! MOV EBX, [EAX+TSS_EFlags] ; Reset TF in case single stepping AND EBX,0FFFFFEFFh MOV [ EAX+TSS_EFlags ] , EBX ;We set the FAULT variable based on which interrupt ; procedure was entered.

Chapter 23 ■ Debugger Code |477 CMP DWORD PTR dbgFAULT,0FFh ;Was the dbgr entered on a FAULT? JE dbg000 ;NO NOTE: Must eventually add SS/ESP for a change in CPL on faults!!! REF - See page 3-4 System Software Writer's Guide XOR EAX, EAX PUSH EAX PUSH EAX CALL FWORD PTR SetXY Display fault message and number at 0 ,0 LEA EAX.dbgFltMsg PUSH EAX PUSH sdbgFltMsg PUSH 40h CALL FWORD PTR TTYOut ; Color Black on RED MOV EAX.dbgFAULT PUSH EAX PUSH OFFSET dbgBuf CALL DDtoHex LEA EAX, dbgBuf PUSH EAX PUSH 8 PUSH 70h CALL FWORD PTR _TTYOut MOV DWORD PTR dbgFAULT, 0FFh reset fault indicator LEA EAX.dbgCRLF PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut XOR EAX, EAX MOV dbgX, EAX INC EAX MOV dbgY, EAX ; Color White on black ;Reset X & Y to 0,1 CALL DbgRegVid CALL dbgDispMenu PUSH dbgX PUSH dbgY CALL FWORD PTR SetXY ; Display BackLink's Register values ; Display menu ;Back to where we were ;Display Instruction at CS:EIP MOV EBX.DbgpTSSSave MOV EAX, [EBX+TSS_EIP] MOV dbgCrntAdd, EAX CALL dbgShowBP PUSH EAX CALL _disassemble MOV NextEIP, EAX ;Get USER pUserTSS This puts the instruction on the line

Part IV ■ The Operating System Source Code Listing 23.2. continued CALL dbgCheckScroll ;Fall through to keyboard loop dbg00: dbg02: dbg03: dbg04: dbg05: ;Now we read the keyboard MOV EAX, OFFSET dbgKeyCode PUSH EAX CALL ReadDbgKbd MOV EAX, dbgKeyCode AND EAX, 0FFh CMP EAX, 1Bh JE dbgExit CMP EAX, 0Fh JNE dbg02 MOV EBX.DbgpTSSSave MOV ECX,[EBX+TSS_EFlags] OR ECX, 000001 00h MOV [EBX+TSS_EFlags],ECX JMP dbgExit CMP EAX, 10h JNE dbg03 MOV EBX, dbgCrntAdd MOV dbgBPAdd, EBX MOV DR0, EBX XOR EAX, EAX MOV DR6, EAX MOV EAX, 00000002h MOV DR7, EAX JMP dbg00 CMP EAX, 11h JNE dbg04 XOR EAX, EAX MOV dbgBPAdd, EAX MOV DR7, EAX JMP dbg00 CMP EAX, 12h JNE dbg05 MOV EBX.DbgpTSSSave MOV EAX, [EBX+TSS_EIP] MOV dbgCrntAdd, EAX CALL dbgShowBP PUSH EAX CALL _disassemble MOV NextEIP, EAX CALL dbgCheckScroll JMP dbg00 CMP EAX, 13H JNE dbg06 CALL dbgDispExchs JMP dbg000 Lop off key status bytes ESCAPE (Exit) ; Single Step (F1) ;Get USER pUserTSS ;Set TF in flags for single step ;Set BP (Current Address - F2) ;Address displayed ;Save it so we know where BP is ;Move into Breakpoint Reg 0 BP0 Set global Clear BP (Current Address - F3) Clear BP saved address Return to CS:EIP (F4) Get USER pUserTSS ;This puts the instruction on the line ;See if we need to scroll up ;Display Exchanges (F5) ;Full display

Chapter 23 ■ Debugger Code dbg06: dbg07: dbg08: dbg09: dbg10: dbg12: dbg13: CMP EAX, 14h JNE dbg07 CALL dbgDispTasks JMP dbg000 CMP EAX, 15h JNE dbg08 JMP dbg00 CMP AL, 16h JNE dbg09 CALL dbgSetAddr PUSH dbgX PUSH dbgY CALL FWORD PTR _SetXY MOV EAX, NextEIP MOV dbgCrntAdd, EAX CALL dbgShowBP PUSH EAX CALL _disassemble MOV NextEIP, EAX CALL dbgCheckScroll JMP dbg00 CMP AL, 17h JNE dbg10 MOV BL, 00 MOV dbgfDumpD, BL CALL dbgDump JMP dbg000 CMP AL, 18h JNE dbg12 MOV BL, 0FFh MOV dbgfDumpD, BL CALL dbgDump JMP dbg14: CMP AL, 01 Ah JNE dbg13 CALL Dbglnfo JMP dbg00 CMP AL, 02h JNE dbg14 MOV EAX, NextEIP MOV dbgCrntAdd, EAX CALL dbgShowBP PUSH EAX CALL _disassemble MOV NextEIP, EAX CALL dbgCheckScroll JMP dbg00 JMP dbg00 Task array display (F6) Not used yet Set Disassembly Address (F8) Sets NextEIP Back to where we were ;This puts the instruction on the line ;See if we need to scroll up ;Memory Dump Bytes (F9) ; Memory Dump DWORDS (F10) 5 ;Info Address dump (F12) ! ; Display next Instruction (Down Arrow) ;This puts the instruction on the line ;See if we need to scroll up ;GO back for another key

480 Part IV ■ The Operating System Source Code Listing 23.2. continued DbgExit LEA EAX.dbgX ; Query XY PUSH EAX LEA EAX.dbgY PUSH EAX CALL FWORD PTR _GetXY PUSH DbgVidSave CALL FWORD PTR _SetVidOwner ; Change screens back MOV EAX, DbgpTSSSave MOV pRunTSS, EAX MOV BX, [EAX+Tid] MOV TSS_Sel, BX JMP FWORD PTR [TSS] ; Return saved pRunTSS ;Set up caller's TSS selector ;Next time we enter the debugger task it will be here! JMP DbgTask ;Back to beginning dbgShowBP: ;This compares the current breakpoint to the address ;we are about to display. If they are the same, ;we put up an asterisk to indicate it's the breakpoint ;EAX must be preserved MOV EBX, dbgCrntAdd MOV ECX, dbgBPAdd CMP EBX, ECX JZ dbgShowBPI RETN dbgShowBPI : PUSH EAX PUSH OFFSET dbgAsterisk PUSH 01 h PUSH 47h CALL FWORD PTR _TTYOut POP EAX RETN ;Address displayed ;BP Address Save EAX across call 3 params to TTYOut Reverse Vid WHITE on RED This sets up and calls to display all of the register information on the right side of the debugger video display DbgRegVid: MOV EBX, DbgpTSSSave MOV ECX, 00 MOV ESI, OFFSET DbgTxt00 XOR EAX, EAX MOV AX,[EBX+TSSNum] CALL DispRegs MOV ECX, 01 ;EBX MUST be DbgpTSSSave ;TSS Display ;Number of this TSS ;EAX Display

MOV ESI, OFFSET DbgTxt01 MOV EAX,[EBX+TSS_EAX] CALL DispRegs Chapter 23 ■ Debugger Code MOV ECX.02 MOV ESI, OFFSET DbgTxt02 MOV EAX,[EBX+TSS_EBX) CALL DispRegs ;EBX Display MOV ECX.03 MOV ESI .OFFSET DbgTxt03 MOV EAX,[EBX+TSS_ECX] CALL DispRegs ;ECX Display MOV ECX.04 MOV ESI, OFFSET DbgTxt04 MOV EAX,[EBX+TSS_EDX] CALL DispRegs ;EDX Display MOV ECX.05 MOV ESI, OFFSET DbgTxt05 MOV EAX,[EBX+TSS_ESI] CALL DispRegs ;ESI Display MOV ECX.06 MOV ESI, OFFSET DbgTxt06 MOV EAX,[EBX+TSS_EDI] CALL DispRegs ;EDI Display MOV ECX.07 MOV ESI, OFFSET DbgTxt07 MOV EAX,[EBX+TSS_EBP] CALL DispRegs ;EBP Display MOV ECX.08 MOV ESI, OFFSET DbgTxt08 XOR EAX.EAX MOV AX,[EBX+TSS_SS] CALL DispRegs ;SS Display MOV ECX.09 MOV ESI, OFFSET DbgTxt09 MOV EAX,[EBX+TSS_ESP] CALL DispRegs ESP Display MOV ECX.10 MOV ESI, OFFSET DbgTxt10 XOR EAX.EAX MOV AX,[EBX+TSS_CS] CALL DispRegs ;CS Display MOV ECX.11 MOV ESI, OFFSET DbgTxtH MOV EAX,[EBX+TSS_EIP] CALL DispRegs MOV ECX.12 MOV ESI, OFFSET DbgTxt12 ;EIP Display ;DS Display

I
482 Part PV The Operating System Source Code Listing 23.2. continued XOR EAX.EAX MOV AX,[EBX+TSS_DS] CALL DispRegs MOV ECX,13 MOV ESI, OFFSET DbgTxt13 XOR EAX.EAX MOV AX, [EBX+TSS_ES] CALL DispRegs MOV ECX.14 MOV ESI, OFFSET DbgTxt14 XOR EAX.EAX MOV AX,[EBX+TSS_FS] CALL DispRegs MOV ECX, 15 MOV ESI, OFFSET DbgTxt15 XOR EAX.EAX MOV AX,[EBX+TSS_GS] CALL DispRegs MOV ECX.16 MOV ESI .OFFSET DbgTxt16 MOV EAX,[EBX+TSS_EFlags] CALL DispRegs MOV ECX.17 MOV ESI, OFFSET DbgTxt17 MOV EAX.CR0 CALL DispRegs MOV ECX.18 MOV ESI, OFFSET DbgTxt18 MOV EAX.CR2 CALL DispRegs MOV ECX, 19 MOV ESI, OFFSET DbgTxt19 MOV EAX.CR3 CALL DispRegs MOV ECX, 20 MOV ESI, OFFSET DbgTxt20 MOV EAX.dbgFltErc CALL DispRegs RETN ;ES Display ; FS Display ;GS Display ;EFlags Display ;CR0 Display ;CR2 Display ;CR3 Display ; Fault Error Code Display This is for Debugger Register display Call with: EAX loaded with value to display (from TSS reg) ECX loaded with number of text line to display on ESI loaded with EA of text line to display We save all registers cause the vid calls don't DispRegs: PUSH EAX ;Save number to display PUSH 66 PUSH ECX CALL FWORD PTR SetXY

Chapter 23 M Debugger Code 483 PUSH ESI PUSH 05h PUSH 07h CALL FWORD PTR TTYOut POP EAX ;Get number back for display PUSH EAX PUSH OFFSET dbgBuf CALL DDtoHex PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR JTYOut POPAD RETN ; This displays the debugger function key menu dbgDispMenu: PUSH 0 ; Display Debugger FKey Menu PUSH 24 CALL FWORD PTR _SetXY LEA EAX.dbgMenu PUSH EAX PUSH 78 PUSH 70h CALL FWORD PTR _TTYOut PUSH 25 PUSH 24 CALL FWORD PTR _SetXY LEA EAX.dbgSpace PUSH EAX PUSH 1 PUSH 07h CALL FWORD PTR JTYOut PUSH 51 PUSH 24 CALL FWORD PTR _SetXY LEA EAX.dbgSpace PUSH EAX PUSH 1 PUSH 07h CALL FWORD PTR _TTYOut RETN ;Allows the user to pick the currently displayed address dbgSetAddr: PUSH 0 ;Goto Query Line

484 | Part PV ■ The Operating System Source Code Listing 23.2. continued PUSH 23 CALL FWORD PTR SetXY LEA EAX, dbgTxtAddr PUSH EAX PUSH 16 PUSH 07h CALL FWORD PTR JTYOut CMP EAX, 0 JNE DumpDone LEA EAX, DbgBuf2 PUSH EAX PUSH cbBufLen2 PUSH 8 LEA EAX, cbBufLen2 PUSH EAX LEA EAX, dbgChar PUSH EAX PUSH 70h CALL FWORD PTR _EditLine MOV AL, dbgChar CMP AL, 0Dh JNE dbgSetAddrDone LEA EAX, dbgBuf2 PUSH EAX LEA EAX, dbgNextAdd PUSH EAX PUSH cbBufLen2 CALL HexToDD CMP EAX, 0 JNE dbgSetAddrDone pEdString Crnt size Max size ptr to size returned ptr to char returned Black On White ; Ignore error if any ;did they exit with CR? ;Convert String to DD ;ptr to string ;ptr to destination DD ; length of string ;dbgDumpAdd has address to dump! MOV EAX, dbgNextAdd MOV NextEIP, EAX dbgSetAddrDone: CALL dbgClearQuery RETN ;Go home. . . J ======== ;Queries user for address then dumps data to screen dbgDump: PUSH 0 PUSH 23 CALL FWORD PTR ;Goto Query Line SetXY LEA EAX, dbgTxtAddr PUSH EAX PUSH 16 PUSH 07h CALL FWORD PTR _TTYOut CMP EAX, 0 JNE DumpDone

Chapter 23 ■ Debugger Code H LEA EAX, DbgBuf2 PUSH EAX PUSH cbBufLen2 PUSH 8 LEA EAX, cbBufLen2 PUSH EAX LEA EAX, dbgChar PUSH EAX PUSH 70h CALL FWORD PTR Ed] pEdString Crnt size Max size ptr to size returned ptr to char returned Black On White ; Ignore error if any MOV AL, dbgChar CMP AL, 0Dh JE dbgDoDump CALL dbgClearQuery RETN ;did they exit with CR? ;Go home. dbgDoDump: LEA EAX, dbgBuf2 PUSH EAX LEA EAX, dbgDumpAdd PUSH EAX PUSH cbBufLen2 CALL HexToDD CMP EAX, 0 JNE DumpDone ;Convert String to DD ;ptr to string ;ptr to destination DD ; length of string ; dbgDumpAdd has address to dump! CALL FWORD PTR _ClrScr dbgDump00: MOV DWORD PTR dbgGPddl , 24 ;line counter begins at 24 dbgDump01 : MOV DWORD PTR dbgGPdd3, 4 ; number of quads per line PUSH dbgDumpAdd ; convert address to text LEA EAX, dbgBuf PUSH EAX CALL DDtoHex LEA EAX, dbgBuf PUSH EAX PUSH 8 PUSH 07h CALL FWORD PTR _TTYOut CMP EAX, 0 JNE DumpDone dbgDump02: MOV DWORD PTR dbgGPdd2, 6 ;byte offset begins at 6 LEA EAX, dbgSpace PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR JTYOut CMP EAX, 0 JNE DumpDone MOV EBX, dbgDumpAdd ;get dump address MOV EAX, [EBX] ;Get what it's pointing to PUSH EAX ;make it a DD Text

Part IV ■ The Operating System Source Code Listing 23.2. continued dumpB: LEA EAX, dbgBuf PUSH EAX CALL DDtoHex MOV AL, dbgfDumpD CMP AL, 0 JE DumpB LEA EAX, dbgBuf PUSH EAX PUSH 8 PUSH 07 CALL FWORD PTR _TTYOut JMP DumpDin LEA EAX, dbgBuf ADD EAX, dbgGPdd2 PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut LEA EAX, dbgSpace PUSH EAX PUSH 1 PUSH 07h CALL FWORD PTR _TTYOut DEC dbgGPdd2 DEC dbgGPdd2 LEA EAX, dbgBuf ADD EAX, dbgGPdd2 PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut LEA EAX, dbgSpace PUSH EAX PUSH 1 PUSH 07h CALL FWORD PTR _TTYOut DEC dbgGPdd2 DEC dbgGPdd2 LEA EAX, dbgBuf ADD EAX, dbgGPdd2 PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR TTYOut LEA EAX, dbgSpace PUSH EAX PUSH 1 ; Dumping DWORDS ;NO - go to display bytes ;Yes display Quad ; Display First byte ; ignore error ;Display 1 spaces ; point to second 2 bytes ;display 2st byte ; ignore error ; display 1 space ;display 3rd byte ignore error a space

Chapter 23 Deb ugger Code DumpDin PUSH 07h CALL FWORD PTR _TTYOut DEC dbgGPdd2 DEC dbgGPdd2 LEA EAX, dbgBuf ADD EAX, dbgGPdd2 PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut INC dbgDumpAdd INC dbgDumpAdd INC dbgDumpAdd INC dbgDumpAdd DEC dbgGPdd3 JNZ dbgDump02 LEA EAX, dbgSpa ce PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut LEA EAX.dbgX PUSH EAX LEA EAX.dbgY PUSH EAX CALL FWORD PTR _GetXY ;display 4th byte ignore error ;done with 4 quads?? ;NO - go back for next 4 bytes ;Yes - Display 2 spaces ;Query XY ;Put 16 TEXT chars on right PUSH dbgX PUSH dbgY MOV EAX, dbgDumpAdd SUB EAX, 16 PUSH EAX PUSH 16 PUSH 07h CALL FWORD PTR _PutVidChars ; ignore error LEA EAX, dbgCRLF PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR TTYOut ;Do CR/LF DEC dbgGPddl JNZ dbgDump01 ;231ines yet?? ;NO LEA EAX, dbgCont ; “Continue” Text PUSH EAX PUSH 31 ;size of “cont text’ PUSH 07h CALL FWORD PTR _TTYOut dbgDump03: MOV EAX, OFFSET dbgKeyCode PUSH EAX

488 I Part IV ■ The Operating System Source Code Listing 23.2. continued CALL ReadDbgKbd MOV EAX, dbgKeyCode AND EAX, 0FFh CMP EAX, 0 JE dbgDump03 CMP EAX, 1Bh JE DumpDone LEA EAX, dbgCRLF PUSH EAX PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut JMP dbgDump00 ;Lop off key status bytes ;Escape (Quit??) ;Do CR/LF DumpDone: CALL FWORD PTR _ClrScr MOV DWORD PTR dbgX, 0 MOV DWORD PTR dbgY, 0 RETN ;Displays exchanges that are allocated along with jmessages or tasks that may be waiting at them dbgDispExchs: MOV DWORD PTR dbgGPdd2, 0 ;Exch# we are on dbgDE00: CALL FWORD PTR ClrScr PUSH 0 PUSH 0 PUSH OFFSET dbgExchMsg PUSH 54 PUSH 07h CALL FWORD PTR PutVidChars MOV DWORD PTR dbgGPddl , 1 Col Line for labels Length of message ;line we are on ;First we do the exchange on the current line dbgDE01 PUSH dbgGPdd2 PUSH OFFSET dbgBuf CALL DDtoHex iConvert Exch number for display ;Col ;Line we are on ;ExchNum PUSH 0 PUSH dbgGPddl PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR _PutVidChars ; ;Then we do the Exch Owner (Job Number) next to it MOV EAX, dbgGPdd2 ; Exch number

Chapter 23 Debugger Code dbgDE03: MOV EDX, SEXCH MUL EDX MOV EDX.prgExch ADD EAX, EDX MOV dbgGPdd3, EAX MOV EBX, [EAX+Owner] XOR EAX, EAX OR EBX, EBX JZ dbgDE03 MOV EAX, [EBX+JobNum] PUSH EAX PUSH OFFSET dbgBuf CALL DDtoHex Compute offset of Exch in rgExch Add offset of rgExch => EAX EAX now pts to Exch pExch into save variable pJCB of Owner into EBX Clear for use as JobNum pNIL? (No owner if so) iConvert Job Number PUSH 10 ;Col PUSH dbgGPddl ;Line PUSH OFFSET dbgBuf ; PUSH 8 PUSH 07h CALL FWORD PTR PutVidChars ; MOV dbgGPdd5, 0 Set pNextMsg to 0 ;See if there is a first message MOV EAX, dbgGPdd3 MOV EBX, [EAX+EHead] OR EBX, EBX JZ dbgDE13 ;pExch -> EAX ;pMsg -> EBX ;Is is NIL (no msg or task) ;Yes. Go to next Exch MOV EBX, [EAX+fEMsg] OR EBX, EBX JZ dbgDE05 MOV EBX, [EAX+EHead] ;MsgFlag -> EBX ;Is is 1 (a message)? ;No, Go check for tasks ;pMsg -> EBX dbgDE04: ;Display Messages MOV DWORD PTR dbgGPdd6, 0 ;Flag to indicate we are doing messages MOV EAX, [EBX+NextLB] ;For next msg in chain (if it exists) MOV dbgGPdd5, EAX ;Save for loop MOV EAX, [EBX+DataHi] ;Get dMsgl MOV EDX, [EBX+DataLo] ;Get dMsg2 PUSH EDX ;Save dMsg2 PUSH EAX ; Convert dMsgl PUSH OFFSET dbgBuf CALL DDtoHex PUSH 20 ;Col PUSH dbgGPddl ;Line PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR _PutVidChars ; POP EDX ;Get dMsg2 back

Part TV ■ The Operating System Source Code Listing 23.2. continued ;Could have left it on stack, but would be confusing later... ; “simplicity of maintenance is as important as simplicity of design’ PUSH EDX ;Convert dMsg2 PUSH OFFSET dbgBuf CALL DDtoHex PUSH 30 ;Col PUSH dbgGPddl ;Line PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR _PutVidChars ; JMP dbgDE07 ;Next line ;See if there are tasks waiting dbgDE05: MOV DWORD PTR dbgGPdd6, 1 MOV DWORD PTR dbgGPdd5, 0 MOV EAX, dbgGPdd3 MOV EBX, [EAX+EHead] OR EBX, EBX JZ dbgDE07 dbgDE06: MOV EAX, [EBX+NextTSS] MOV dbgGPdd5, EAX XOR EAX, EAX MOV AX, [EBX+TSSNum] ;Flag to indicate we are doing tasks ;Clear pNextTask pExch -> EAX pTSS -> EBX Is is 0 (no TSS)? PUSH EAX ;Conv PUSH OFFSET dbgBuf CALL DDtoHex PUSH 50 ;Col PUSH dbgGPddl ;Line PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR PutVidChars ; ;Save ptr to next task if it exists ;Get Number of Task at exch Convert Task Number dbgDE07: INC dbgGPddl ;Next line CMP DWORD PTR dbgGPddl, 23 ;23 lines yet? JB dbgDE09 ;No dbgDE08: PUSH 0 Col PUSH 24 Line PUSH OFFSET dbgCont PUSH 31 leng PUSH 07h CALL FWORD PTR PutVidChars ; MOV EAX, OFFSET dbgKeyCode PUSH EAX length of Cont string

Chapter 23 ■ Debugger Code CALL ReadDbgKbd MOV EAX, dbgKeyCode AND EAX, 0FFh CMP EAX, 1Bh JE dbgDEDone ;Lop off key status byt< ;Escape (Quit??) CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges JAE dbgDEDone ; All Exchs displayed CALL FWORD PTR _ClrScr PUSH 0 PUSH 0 PUSH OFFSET dbgExchMsg PUSH 54 PUSH 07h CALL FWORD PTR _PutVidChars ; MOV DWORD PTR dbgGPddl , 1 ;line. We are on line 1 again Col Line for labels Length of message dbgDE09: MOV EBX, dbgGPdd5 XOR EBX, EBX JZ dbgDE13 MOV EAX, dbgGPdd6 OR EAX, EAX JNZ dbgDE06 JMP dbgDE04 ;Set up to loop for next msg/task ;Another pointer in the link? ;No ;NonZero if we are doing tasks ;Tasks ;Messages dbgDEl3: INC dbgGPdd2 ; Exch number CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges JAE dbgDE08 JMP dbgDE01 dbgDEDone: CALL FWORD PTR _ClrScr MOV DWORD PTR dbgX, 0 MOV DWORD PTR dbgY, 0 RETN Go back for prompt (to pause) Back to display new exch num Displays Tasks that are active along with pertinent address info about them dbgDispTasks: MOV DWORD PTR dbgGPdd2, 1 dbgDT00: CALL FWORD PTR _ClrScr PUSH 0 PUSH 0 PUSH OFFSET dbgTaskMsg PUSH 54 PUSH 07h CALL FWORD PTR _PutVidChars MOV DWORD PTR dbgGPddl, 1 ;Task# we are on Col Line for labels Length of message line we are on ; First we get pTSS and see if it is valid ;If so, we get all the data BEFORE we display it ;If not, we increment TSS number and go back ;for the next one

I
492 Part PV ■ The Operating System Source Code Listing 23.2. continued dbgDT01 ;We get pJCB out of TSS and get JobNum from JCB dbgDT02: dbgDT03: MOV EAX, dbgGPdd2 CMP EAX, 1 JNE dbgDT02 MOV EBX, OFFSET MonTSS JMP SHORT dbgDT04 CMP EAX, 2 JNE dbgDT03 MOV EBX, OFFSET DbgTSS JMP SHORT dbgDT04 MOV EBX, pDynTSSs DEC EAX DEC EAX DEC EAX MOV ECX, 512 MUL ECX ADD EBX, EAX ; Task number ; Is this TSS 1 (Static memory) Is this TSS 2 (Static memory) iMake TSS Num offset in dynamic array iof TSSs ;EBX points to TSS! dbgDT04: ;EBX has pTSS of interest MOV dbgGPdd5, EBX XOR ECX, ECX MOV CL, [EBX+Priority] MOV dbgGPdd6, ECX MOV EAX, [EBX+TSS_pJCB] ; EAX has pJCB OR EAX, EAX JNZ dbgDT05 MOV EAX, dbgGPdd2 INC EAX CMP EAX, nTSS JE dbgDT06 MOV dbgGPdd2, EAX JMP SHORT dbgDT01 Save pTSS for display Priority of this task EAX has pJCB . NON zero means it's valid ;Not used, go for next Task number ;back for next one dbgDT05: ;EAX now pJCB MOV dbgGPdd4, EAX MOV EBX, [EAX] MOV dbgGPdd3, EBX ;Save pJCB for display ;Job number is first DD in JCB PUSH dbgGPdd2 PUSH OFFSET dbgBuf CALL DDtoHex PUSH 0 PUSH dbgGPddi PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR PutVidChars ;Convert TSS number for display ;Col ;Line we are on ;TaskNum PUSH dbgGPdd3 PUSH OFFSET dbgBuf CALL DDtoHex PUSH 10 ;Convert and display Job number ;Col

Chapter 23 B Debugger Code PUSH dbgGPddl PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWOP.D PTR PutVidChars Line we are on Size PUSH dbgGPdd4 PUSH OFFSET dbgBuf CALL DDtoHex PUSH 20 PUSH dbgGPddl PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR PutVidChars ; Convert and display pJCB Col Line we are on ; Convert and display pTSS PUSH dbgGPddS PUSH OFFSET dbgBuf ; CALL DDtoHex PUSH 30 ;Col PUSH dbgGPddl ;Line we are on PUSH OFFSET dbgBuf ; PUSH 8 ;Size PUSH 07h CALL FWORD PTR PutVidChars ; PUSH dbgGPdd6 PUSH OFFSET dbgBuf CALL DDtoHex PUSH 40 PUSH dbgGPddl PUSH OFFSET dbgBuf ; PUSH 8 PUSH 07h CALL FWORD PTR PutVidChars ;Convert and display Priority ;Col ;Line we are Size MOV EAX, dbgGPdd2 INC EAX CMP EAX, nTSS JE dbgDT06 MOV dbgGPdd2, EAX ;go for next Task number ;Save it for the top dbgDT06: INC dbgGPddl CMP DWORD PTR dbgGPddl, JAE dbgDT06 JMP dbgDT01 ;Next line 23 ;23 lines yet? ;Yes, continue prompt ;No, go back for next PUSH 0 ;Col PUSH 24 ;Line PUSH OFFSET dbgCont PUSH 31 PUSH 07h CALL FWORD PTR PutVidChars length of Cont string MOV EAX, OFFSET dbgKeyCode PUSH EAX CALL ReadDbgKbd MOV EAX, dbgKeyCode

494 ^art ^ " The Operating System Source Code Listing 23.2. continued AND EAX, OFFh ; Lop off key status bytes CMP EAX, 1Bh ; Escape (Quit??) JE dbgDTDone JMP dbgDT00 ;Back for next screen dbgDTDone: CALL FWORD PTR _ClrScr MOV DWORD PTR dbgX, 0 MOV DWORD PTR dbgY, 0 RETN ; This is for Debugger Address Info display ; Call with EAX loaded with address to display (L inear Address) ESI loaded with EA of text line to di splay ; We save all registers cause the vid calls don't DispAddr: PUSHAD PUSH EAX ;Save number to display PUSH ESI ;ptr to line PUSH 06h ; Length of line PUSH 07h ;Vid Attribute CALL FWORD PTR _TTYOut ;Do it POP EAX ;Get number back for display PUSH EAX PUSH OFFSET dbgBuf CALL DDtoHex PUSH OFFSET dbgBuf PUSH 8 PUSH 07h CALL FWORD PTR _TTYOut PUSH OFFSET dbgCRLF PUSH 2 PUSH 07h CALL FWORD PTR _TTYOut CALL dbgCheckScroll POPAD RETN i ;DbgInfo - Displays important linear address for the OS Dbglnfo: MOV ESI .OFFSET DbgM0 ; IDT LEA EAX, IDT CALL DispAddr MOV ESI, OFFSET DbgM1 ;GDT LEA EAX, GDT CALL DispAddr

Chapter 23 Debugger Code MOV ESI, OFFSET DbgM2 MOV EAX, pRQBs CALL DispAddr MOV ESI .OFFSET DbgM3 MOV EAX, OFFSET MonTSS CALL DispAddr MOV ESI, OFFSET DbgM4 MOV EAX, pDynTSSs CALL DispAddr MOV ESI, OFFSET DbgM5 LEA EAX, rgLBs CALL DispAddr MOV ESI, OFFSET DbgM6 LEA EAX, RdyQ CALL DispAddr MOV ESI, OFFSET DbgM7 MOV EAX, pJCBs CALL DispAddr MOV ESI, OFFSET DbgM8 LEA EAX, rgSVC CALL DispAddr MOV ESI, OFFSET DbgM9 MOV EAX, prgExch CALL DispAddr MOV ESI, OFFSET DbgPA LEA EAX, rgPAM CALL DispAddr MOV ESI, OFFSET DbgMB LEA EAX, rgTmrBlks CALL DispAddr RETN ;RQBs ; pTSS3 LBs ;RdyQ ;JCBs ;SVCs Exchs ;PAM (Page Allocation map) Timer Blocks ;A11 of the debugger text is displayed in a window ; between columns 0 and 66, and line 0 to 24. The other ;areas are reserved for the menu, query line, ;and the register display. ;This checks to see if the cursor is on line 23. ;If so, we scroll up the text area by one line. dbgCheckScroll: LEA EAX.dbgX PUSH EAX LEA EAX.dbgY PUSH EAX CALL FWORD PTR _GetXY CMP DWORD PTR dbgY, 23 JB dbgNoScroll ;Query XY (See what line and Col) ;Are we at bottom (just above menu)?? ;No, go back for next key PUSH 0 PUSH 0 PUSH 66 PUSH 24 PUSH 1 CALL FWORD PTR ScrollVid ;Yes, Scroll test area (Col 0-64, Line 0-24) ;Columns 0-65 ;Lines 0-23 ;fUp (1) PUSH 0 PUSH 22 ;Got to Column 0, Line 22

496 ^art ^ " ^e operating System Source Code Listing 23.2. continued CALL FWORD PTR _SetXY dbgNoScroll: RETN Clear the query line (Line 23, 40 chars) dbgClearQuery: PUSH 0 ;Col 0, Line 23 PUSH 23 PUSH OFFSET dbgClear PUSH 40 PUSH 07h CALL FWORD PTR PutVidChars ; ignore error RETN module end

Powered by TurnKey Linux.