;//--------------------------------------------------------------- ;// sysregs.s (for in-class programming exercise) ;// ;// This bootsector program is supposed to display the value ;// found in the two 48-bit descriptor-table registers (GDTR ;// and IDTR) and the value found in the two 16-bit segment- ;// selector system registers (LDTR and TR). Only the first ;// two of these registers can be accessed in real-mode; the ;// remaining two registers are only accessible once the cpu ;// has entered protected-mode. It is left, as an exercise, ;// for you to supply the additional instructions which will ;// enter protected-mode, obtain the register-values in LDTR ;// and TR, and then return to real-mode to display the full ;// set of these four register-values in hexadecimal format. ;// ;// assemble with: $ as86 sysregs.s -b sysregs.b ;// install using: # dd if=sysregs.b of=/dev/fd0 ;// ;// programmer: ALLAN CRUSE ;// written on: 04 FEB 2004 ;//--------------------------------------------------------------- .SECT .TEXT ;----------------------------------------------------------------- start: cli ; enter critical section mov ax, cs ; address base segment mov ss, ax ; with SS register mov sp, #0x7C00 ; stacktop = 0000:7C00 sti ; leave critical section jmpf #main, #0x07C0 ; renormalizes CS and IP ;----------------------------------------------------------------- regGDTR: .WORD 0, 0, 0 ; reserved for GDTR value regIDTR: .WORD 0, 0, 0 ; reserved for IDTR value regLDTR: .WORD 0 ; reserved for LDTR value regTR: .WORD 0 ; reserved for TR value ;----------------------------------------------------------------- main: ; setup registers DS and ES to address our data mov ax, cs ; address this segment mov ds, ax ; with DS register mov es, ax ; also ES register ; convert GDTR contents to hexadecimal string sgdt regGDTR ; store GDTR to memory push word [regGDTR+0] ; push GDTR word #0 push word [regGDTR+2] ; push GDTR word #1 push word [regGDTR+4] ; push GDTR word #2 lea di, report+6 ; point DS:DI to output pop ax ; recover word #2 call ax2hex ; convert word to hex pop ax ; recover word #1 call ax2hex ; convert word to hex pop ax ; recover word #0 call ax2hex ; convert word to hex ; convert IDTR contents to hexadecimal string sidt regIDTR ; store IDTR to memory push word [regIDTR+0] ; push IDTR word #0 push word [regIDTR+2] ; push IDTR word #1 push word [regIDTR+4] ; push IDTR word #2 lea di, report+27 ; point DS:DI to output pop ax ; recover word #2 call ax2hex ; convert word to hex pop ax ; recover word #1 call ax2hex ; convert word to hex pop ax ; recover word #0 call ax2hex ; convert word to hex ; display the message-string mov ah, #0x0F ; display-page to BH int 0x10 ; invoke BIOS service mov ah, #0x03 ; cursor-locn to DH,DL int 0x10 ; invoke BIOS service lea bp, report ; ES:BP=string-address mov cx, msglen ; CX = string's length mov bl, #0x3F ; BL = display-colors mov ax, #0x1301 ; write_string function int 0x10 ; invoke BIOS service ; await user keypress, then reboot xor ah, ah ; get_keyboard_input int 0x16 ; invoke BIOS service int 0x19 ; BIOS reboot service ;----------------------------------------------------------------- ax2hex: ; converts value in AX to hexadecimal string at DS:DI pusha ; save general registers mov dx, ax ; copy AX-value into DX mov cx, #4 ; count of nybbles in DX nxnyb: rol dx, #4 ; shift next nybble to DL mov al, dl ; then copy DL to AL and al, #0x0F ; isolate the low nybble cmp al, #10 ; -- Lopez algorithm -- sbb al, #0x69 ; -- converts nybble -- das ; -- into ascii code -- mov [di], al ; put numeral in buffer inc di ; then advance pointer loop nxnyb ; convert another nybble popa ; recover saved registers add di, #4 ; advance dest'n pointer ret ; back to calling routine ;----------------------------------------------------------------- report: .ASCII " GDTR=xxxxxxxxxxxx \n\r" .ASCII " IDTR=xxxxxxxxxxxx \n\r" .ASCII " LDTR=xxxx TR=xxxx \n\r" msglen: .WORD * - report ;----------------------------------------------------------------- ;----------------------------------------------------------------- .ORG 510 ; boot-signature's offset .BYTE 0x55, 0xAA ; value of boot-signature ;----------------------------------------------------------------- END