那麼一來,用真實模式的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 ----------
[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 @@"
沒有留言:
發佈留言