看來是教科書,看過之後一些有關Assembly的概念比較清晰了,也了解多了常用的Instruction的詳細資訊及一些programming技巧。
今次寫了一個印列所有記憶體內容的kernel,按一下任意鍵就會跳下一版。
這次在每個function裡都加了push及pop,所有在function裡用過的register都會先push,最後pop回來,那麼以後用這些function時就不用怕function內會改變某register了。雖然這樣做會減低function的速度,可是如果不這樣做,寫code的時候真是會死人的。(每次都要去看看要用的function改過什麼register ^^")
之後想用這個programme來研究(體會?)一下記憶體內現在有些什麼。
---------- kernel.asm ----------
;*********************************************
; ABCOS - Kernel
;*********************************************
bits 32
org 0x1000
MOV ESI, 0x00
MOV BX, 0
Main_loop:
CALL GetKeyboard
CALL ClearScreen
CALL PrintMemory_20Line
JMP Main_loop
HLT
; *** Print Memory: Print 20 lines ***
; ESI = First memory location to be printed
; BH = Y (row) position
; BL = X (column) position
; Output:
; ESI = ESI + 16d * 20d
; (BH, BL unchange)
PrintMemory_20Line:
PUSH CX
PUSH BX
MOV CL, 20
PrintMemory_20Line_loop:
CALL PrintMemory_OneLine
LOOP PrintMemory_20Line_loop
POP BX
POP CX
RET
; *** End of Print Memory: Print 20 lines ***
; *** Print Memory: Print only one line ***
; ESI = First memory location to be printed
; BH = Y (row) position
; BL = X (column) position
; Output:
; ESI = ESI + 16d
; BH = BH + 1 (BL unchange)
PrintMemory_OneLine:
PUSH EAX ; Save used registers
PUSH CX
PUSH BX
MOV EAX, ESI
CALL PrintHex32 ; Print Address
MOV AL, 60d ; String character start position
MOV BL, 0xA ; Hex character start position
MOV CX, 0x0F ; Print 16 16-bits
PrintMemory_OneLine_loop:
MOV DL, [ESI]
CALL PrintHex ; Print Hex character
INC AL ; String column position +1
MOV AH, BL ; Save Hex column position
MOV BL, AL ; Use String column position to call PrintChar
CALL PrintChar ; Print String character
MOV BL, AH ; Restore Hex column position
INC ESI
ADD BL, 3
LOOP PrintMemory_OneLine_loop
POP BX ; Restore used registers
INC BH
POP CX
POP EAX
RET
; *** End of Print Memory: Print only one line ***
; *** Get keyboard input (blocked) ***
; Output: DL (Scan Code Set)
GetKeyboard:
IN AL, 0x64
TEST AL, 0x01
JZ GetKeyboard
IN AL, 0x60
MOV DL, AL
GetKeyboard_loop:
IN AL, 0x64
TEST AL, 0x01
JZ GetKeyboard_loop
IN AL, 0x60
; peter: not handle special key yet
RET
; *** End of Get keyboard input (blocked) ***
; *** Define screen constant ***
%define VIDMEM 0xB8000 ; video memory start address
%define VIDMEM_END 0xB8FA0 ; video memory last address
%define SCR_COLS 80
%define SCR_ROWS 25
; *** Set cursor position ***
; BH = Y (row) position
; BL = X (column) position
SetCursor:
MOV AX, SCR_COLS
MUL BH
XOR BH, BH
ADD AX, BX
MOV BX, AX ; BX = BH * SCR_COLS + BL
MOV AL, 0x0F ; Cursor location low byte index
MOV DX, 0x03D4 ; Write it to the CRT index register
OUT DX, AL
MOV AL, BL ; The current location is in EBX. BL contains the low byte, BH high byte
MOV DX, 0x03D5 ; Write it to the data register
OUT DX, AL ; low byte
MOV AL, 0x0E ; Cursor location high byte index
MOV DX, 0x03D4 ; Write to the CRT index register
OUT DX, AL
MOV AL, BH ; the current location is in EBX. BL contains low byte, BH high byte
MOV DX, 0x03D5 ; Write it to the data register
OUT DX, AL ; high byte
RET
; *** End of Set cursor position ***
; *** Print character in text mode ***
; DL = Ascii code of character
; BH = Y (row) position
; BL = X (column) position
PrintChar:
PUSH EAX
PUSH BX
PUSH EDI
PUSH DX
MOV EAX, SCR_COLS
MUL BH ; AX = 80d or 50h, BH max = 24d or 18h
XOR BH, BH
ADD AX, BX ; AX max = 1920d or 780h, result AX max = 2000d or 7D0h
ADD AX, AX ; result AX max = 4000d or FA0h
MOV EDI, EAX ; DI = ( BH * SCR_COLS + BL ) * 2
ADD EDI, VIDMEM
MOV DH, 0x7 ; character attribute
MOV [EDI], DX ; print character
POP DX
POP EDI
POP BX
POP EAX
RET
; *** End of Print character in text mode ***
; *** Print String in text mode ***
; SI = Address of String, string end by 0 (eg. MOV SI, msg)
; BH = Y (row) start position
; BL = X (column) start position
PrintString:
MOV EAX, SCR_COLS
MUL BH ; AX = 80d or 50h, BH max = 24d or 18h
XOR BH, BH
ADD AX, BX ; AX max = 1920d or 780h, result AX max = 2000d or 7D0h
ADD AX, AX ; result AX max = 4000d or FA0h
MOV EDI, EAX ; DI = ( BH * SCR_COLS + BL ) * 2
ADD EDI, VIDMEM
PrintString_loop:
MOV AL, [SI]
CMP AL, 0
JE PrintString_end
MOV AH, 0x7 ; character attribute
MOV [EDI], AX ; print character that BL point to
INC SI
INC EDI
INC EDI
CMP EDI, VIDMEM_END
JE PrintString_end
JMP PrintString_loop
PrintString_end:
RET
; *** End of Print String in text mode ***
; *** Print Hex number in text mode ***
; DL = hex value to print (max: FFh)
; BH = Y (row) position
; BL = X (column) position
PrintHex:
PUSH SI
PUSH DX
PUSH BX
MOV DH, 0
PUSH DX
PUSH BX
SHR DL, 4
MOV SI, DX
MOV DL, [PrintHex_chars+SI]
CALL PrintChar
POP BX
POP SI
AND SI, 0x0F
MOV DL, [PrintHex_chars+SI]
INC BL
CALL PrintChar
POP BX
POP DX
POP SI
RET
PrintHex_chars db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
; *** End of Print Hex number in text mode ***
; *** Print 32 bits Hex ***
; EAX = Need to print this
; BH = Y (row) position
; BL = X (column) position
PrintHex32:
PUSH BX
ROL EAX, 8
MOV DL, AL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
POP BX
RET
; *** End of Print 32 bits Hex ***
; *** Clear Screen in text mode ***
ClearScreen:
MOV EDI, VIDMEM
MOV CX, 2000
ClearScreen_loop:
MOV word [EDI], 0x0720
ADD EDI, 2
LOOP ClearScreen_loop
RET
; *** End of Clear Screen in text mode ***
---------- kernel.asm ----------
> nasm d:\os\kernel.asm -f bin -o d:\os\kernel.bin
> copy /b /y loader.bin+kernel.bin boot.img
;*********************************************
; ABCOS - Kernel
;*********************************************
bits 32
org 0x1000
MOV ESI, 0x00
MOV BX, 0
Main_loop:
CALL GetKeyboard
CALL ClearScreen
CALL PrintMemory_20Line
JMP Main_loop
HLT
; *** Print Memory: Print 20 lines ***
; ESI = First memory location to be printed
; BH = Y (row) position
; BL = X (column) position
; Output:
; ESI = ESI + 16d * 20d
; (BH, BL unchange)
PrintMemory_20Line:
PUSH CX
PUSH BX
MOV CL, 20
PrintMemory_20Line_loop:
CALL PrintMemory_OneLine
LOOP PrintMemory_20Line_loop
POP BX
POP CX
RET
; *** End of Print Memory: Print 20 lines ***
; *** Print Memory: Print only one line ***
; ESI = First memory location to be printed
; BH = Y (row) position
; BL = X (column) position
; Output:
; ESI = ESI + 16d
; BH = BH + 1 (BL unchange)
PrintMemory_OneLine:
PUSH EAX ; Save used registers
PUSH CX
PUSH BX
MOV EAX, ESI
CALL PrintHex32 ; Print Address
MOV AL, 60d ; String character start position
MOV BL, 0xA ; Hex character start position
MOV CX, 0x0F ; Print 16 16-bits
PrintMemory_OneLine_loop:
MOV DL, [ESI]
CALL PrintHex ; Print Hex character
INC AL ; String column position +1
MOV AH, BL ; Save Hex column position
MOV BL, AL ; Use String column position to call PrintChar
CALL PrintChar ; Print String character
MOV BL, AH ; Restore Hex column position
INC ESI
ADD BL, 3
LOOP PrintMemory_OneLine_loop
POP BX ; Restore used registers
INC BH
POP CX
POP EAX
RET
; *** End of Print Memory: Print only one line ***
; *** Get keyboard input (blocked) ***
; Output: DL (Scan Code Set)
GetKeyboard:
IN AL, 0x64
TEST AL, 0x01
JZ GetKeyboard
IN AL, 0x60
MOV DL, AL
GetKeyboard_loop:
IN AL, 0x64
TEST AL, 0x01
JZ GetKeyboard_loop
IN AL, 0x60
; peter: not handle special key yet
RET
; *** End of Get keyboard input (blocked) ***
; *** Define screen constant ***
%define VIDMEM 0xB8000 ; video memory start address
%define VIDMEM_END 0xB8FA0 ; video memory last address
%define SCR_COLS 80
%define SCR_ROWS 25
; *** Set cursor position ***
; BH = Y (row) position
; BL = X (column) position
SetCursor:
MOV AX, SCR_COLS
MUL BH
XOR BH, BH
ADD AX, BX
MOV BX, AX ; BX = BH * SCR_COLS + BL
MOV AL, 0x0F ; Cursor location low byte index
MOV DX, 0x03D4 ; Write it to the CRT index register
OUT DX, AL
MOV AL, BL ; The current location is in EBX. BL contains the low byte, BH high byte
MOV DX, 0x03D5 ; Write it to the data register
OUT DX, AL ; low byte
MOV AL, 0x0E ; Cursor location high byte index
MOV DX, 0x03D4 ; Write to the CRT index register
OUT DX, AL
MOV AL, BH ; the current location is in EBX. BL contains low byte, BH high byte
MOV DX, 0x03D5 ; Write it to the data register
OUT DX, AL ; high byte
RET
; *** End of Set cursor position ***
; *** Print character in text mode ***
; DL = Ascii code of character
; BH = Y (row) position
; BL = X (column) position
PrintChar:
PUSH EAX
PUSH BX
PUSH EDI
PUSH DX
MOV EAX, SCR_COLS
MUL BH ; AX = 80d or 50h, BH max = 24d or 18h
XOR BH, BH
ADD AX, BX ; AX max = 1920d or 780h, result AX max = 2000d or 7D0h
ADD AX, AX ; result AX max = 4000d or FA0h
MOV EDI, EAX ; DI = ( BH * SCR_COLS + BL ) * 2
ADD EDI, VIDMEM
MOV DH, 0x7 ; character attribute
MOV [EDI], DX ; print character
POP DX
POP EDI
POP BX
POP EAX
RET
; *** End of Print character in text mode ***
; *** Print String in text mode ***
; SI = Address of String, string end by 0 (eg. MOV SI, msg)
; BH = Y (row) start position
; BL = X (column) start position
PrintString:
MOV EAX, SCR_COLS
MUL BH ; AX = 80d or 50h, BH max = 24d or 18h
XOR BH, BH
ADD AX, BX ; AX max = 1920d or 780h, result AX max = 2000d or 7D0h
ADD AX, AX ; result AX max = 4000d or FA0h
MOV EDI, EAX ; DI = ( BH * SCR_COLS + BL ) * 2
ADD EDI, VIDMEM
PrintString_loop:
MOV AL, [SI]
CMP AL, 0
JE PrintString_end
MOV AH, 0x7 ; character attribute
MOV [EDI], AX ; print character that BL point to
INC SI
INC EDI
INC EDI
CMP EDI, VIDMEM_END
JE PrintString_end
JMP PrintString_loop
PrintString_end:
RET
; *** End of Print String in text mode ***
; *** Print Hex number in text mode ***
; DL = hex value to print (max: FFh)
; BH = Y (row) position
; BL = X (column) position
PrintHex:
PUSH SI
PUSH DX
PUSH BX
MOV DH, 0
PUSH DX
PUSH BX
SHR DL, 4
MOV SI, DX
MOV DL, [PrintHex_chars+SI]
CALL PrintChar
POP BX
POP SI
AND SI, 0x0F
MOV DL, [PrintHex_chars+SI]
INC BL
CALL PrintChar
POP BX
POP DX
POP SI
RET
PrintHex_chars db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
; *** End of Print Hex number in text mode ***
; *** Print 32 bits Hex ***
; EAX = Need to print this
; BH = Y (row) position
; BL = X (column) position
PrintHex32:
PUSH BX
ROL EAX, 8
MOV DL, AL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
ROL EAX, 8
MOV DL, AL
INC BL
INC BL
CALL PrintHex
POP BX
RET
; *** End of Print 32 bits Hex ***
; *** Clear Screen in text mode ***
ClearScreen:
MOV EDI, VIDMEM
MOV CX, 2000
ClearScreen_loop:
MOV word [EDI], 0x0720
ADD EDI, 2
LOOP ClearScreen_loop
RET
; *** End of Clear Screen in text mode ***
---------- kernel.asm ----------
> nasm d:\os\kernel.asm -f bin -o d:\os\kernel.bin
> copy /b /y loader.bin+kernel.bin boot.img
沒有留言:
發佈留言