您的位置:首页 > 其它

[翻译]如何用汇编创建一个基础内核 (四)

2011-03-13 15:17 453 查看
原文是 OSDev Wiki上的一个 Tutorials 文章。

1,第一个启动扇区

2,使用BIOS写消息

3,看看机器码

4,不用BIOS向屏幕打印输出

5,中断

6,进入保护模式

7,非实模式

8,32 位打印输出

附录A,更多资讯


4,不用BIOS向屏幕打印字符

我知道这开始看起来像一个不完整的汇编教程,但有,我这样做的背后是有原因的。也就是说,

当进入了保护模式,前面说的许多问题都得到了解决,减少了混乱。

下面这个例子是打印一个字符串和一个内存位置的内容( 这是视频内存中的第一个字符)。其目的是

展示如何在不使用BIOS的情况下以文本的方式向屏幕打印。由于是已经转换到十六进制,因而可以显示。

我们可以检查寄存器和内存值。

堆栈是被包括进来,但闲置没用。

代码:

;=====================================
; nasmw boot.asm -f bin -o boot.bin
; partcopy boot.bin 0 200 -f0

[ORG 0x7c00]      ; add to offsets
xor ax, ax    ; make it zero
mov ds, ax   ; DS=0
mov ss, ax   ; stack starts at 0
mov sp, 0x9c00   ; 200h past code start

mov ax, 0xb800   ; text video memory
mov es, ax

mov si, msg   ; show text string
call sprint

mov ax, 0xb800   ; look at video mem
mov gs, ax
mov bx, 0x0000   ; 'W'=57 attrib=0F
mov ax, [gs:bx]

mov  word [reg16], ax ;look at register
call printreg16

hang:
jmp hang

;----------------------
dochar:   call cprint         ; print one character
sprint:   lodsb      ; string char to AL
cmp al, 0
jne dochar   ; else, we're done
add byte [ypos], 1   ;down one row
mov byte [xpos], 0   ;back to left
ret

cprint:   mov ah, 0x0F   ; attrib = white on black
mov cx, ax    ; save char/attribute
movzx ax, byte [ypos]
mov dx, 160   ; 2 bytes (char/attrib)
mul dx      ; for 80 columns
movzx bx, byte [xpos]
shl bx, 1    ; times 2 to skip attrib

mov di, 0        ; start of video memory
add di, ax      ; add y offset
add di, bx      ; add x offset

mov ax, cx        ; restore char/attribute
stosw              ; write char/attribute
add byte [xpos], 1  ; advance to right

ret

;------------------------------------

printreg16:
mov di, outstr16
mov ax, [reg16]
mov si, hexstr
mov cx, 4   ;four places
hexloop:
rol ax, 4   ;leftmost will
mov bx, ax   ; become
and bx, 0x0f   ; rightmost
mov bl, [si + bx];index into hexstr
mov [di], bl
inc di
dec cx
jnz hexloop

mov si, outstr16
call sprint

ret

;------------------------------------

xpos   db 0
ypos   db 0
hexstr   db '0123456789ABCDEF'
outstr16   db '0000', 0  ;register value string
reg16   dw    0  ; pass values to printreg16
msg   db "What are you doing, Dave?", 0
times 510-($-$$) db 0
db 0x55
db 0xAA
;==================================


(第四篇END)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: