星期二

印列記憶體內容

剛剛K完這本書 -> Assembly Language for Intel-Based Computers (by Kip R.Irvine, Prentice Hall, 4th Edition)

看來是教科書,看過之後一些有關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

沒有留言: