星期三

印出Registers

好了,書已看完。再來做一點實務,試試顯示一些開機之後軟/硬體的資料。

那麼一來,用真實模式的Assembly Kernel會比較方便吧~ 等等,唔... 直接用Boot Loader來做更好吧~~

先做一個測試的... 咦? 間中行到,間中又行不到? 研究了一點點時間,原來我把data放了在最上面,因為現在的情況,編譯器會把所有東東直接轉換的,另一方面,又會在最開始的地方開始執行,所以一開始會把data當code執行的,把data放在最下面就沒問題了。

有關bit的基本東東:
1 bit = 0/1
4 bits = 1111 = F = nibble
8 bits = 11111111 = FF = byte = AH/AL
16 bits = FFFF = 2 bytes = word = AX

先來一個簡單的,當是熱身,把Register印出來的。
---------- loader.asm ----------
[BITS 16]

[ORG 0x7C00]

   CALL PrintRegisters

   JMP $

; ----------------------------------------
; PrintRegisters
; ----------------------------------------
PrintRegisters:
   PUSH SS
   PUSH ES
   PUSH DS
   PUSH CS
   PUSH SP
   PUSH BP
   PUSH DI
   PUSH SI
   PUSH DX
   PUSH CX
   PUSH BX
   PUSH AX

   MOV SI, lbl_ax
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_bx
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_cx
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_dx
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_enter
   CALL PrintString

   MOV SI, lbl_si
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_di
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_bp
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_sp
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_enter
   CALL PrintString

   MOV SI, lbl_cs
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_ds
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_es
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_ss
   CALL PrintString
   POP DX
   CALL Print16bits

   MOV SI, lbl_enter
   CALL PrintString
   RET

; ----------------------------------------
; Print16bits - move 16bits to DX
; ----------------------------------------
Print16bits:
   MOV AL, DH
   CALL PrintByte
   MOV AL, DL
   CALL PrintByte
   RET

; ----------------------------------------
; PrintByte - move byte to AL
; ----------------------------------------
PrintByte:
   MOV CL, AL

   ; Handle first 4 bits
   SHR AL, 4
   CALL PrintNibble

   ; Handle last 4 bits
   MOV AL, CL
   AND AL, 0x0F
   CALL PrintNibble

   RET

; ----------------------------------------
; PrintNibble - move 4 bits to lower AL, ie. 0A, we print "A"
; ----------------------------------------
PrintNibble:
   MOV AH, 0Eh ; INT 10h parameter - Write a character
   MOV BH, 0h ; Page number
   MOV BL, 0x07 ; ? play something ?

   CMP AL, 0x0A
   JB PrintNibble_Num
   ADD AL, 37h
   JMP PrintNibble_Print
PrintNibble_Num:
   ADD AL, 30h
PrintNibble_Print:
   INT 10h
   RET

; ----------------------------------------
; PrintLine - move string address to SI, with new line
; ----------------------------------------
PrintLine:
   CALL PrintString
   MOV AL, 10
   INT 10h
   MOV AL, 13
   INT 10h
   RET

; ----------------------------------------
; PrintString - move string address to SI
; ----------------------------------------
PrintString:
   MOV AH, 0Eh ; INT 10h parameter - Write a character
   MOV BH, 0h ; Page number
   MOV BL, 0x07 ; ? play something ?
NextChar:
   LODSB
   OR AL, AL
   JZ PrintLine_End
   INT 10h
   JMP NextChar
PrintLine_End:
   RET

lbl_enter db 10, 13, 0
lbl_ax db " AX=", 0
lbl_bx db " BX=", 0
lbl_cx db " CX=", 0
lbl_dx db " DX=", 0
lbl_si db " SI=", 0
lbl_di db " DI=", 0
lbl_bp db " BP=", 0
lbl_sp db " SP=", 0
lbl_cs db " CS=", 0
lbl_ds db " DS=", 0
lbl_es db " ES=", 0
lbl_ss db " SS=", 0

TIMES 510 - ($ - $$) db 0 ;fill the rest of sector with 0
DW 0xAA55 ; add boot signature at the end of bootloader
---------- loader.asm ----------

照例開啟NASM Shell,輸入:

> nasm loader.asm -f bin -o boot.img

在Bochs模擬器上測試,成功:

AX=AA55 BX=0000 CX=0000 DX=0000
SI=3238 DI=FFAC BP=0000 SP=FFCC
CS=0000 DS=0000 ES=0000 SS=0000

FYI,上面那個programme已經用了298bytes @@"

沒有留言: