操作系统开发 – 婴儿教程 4
扫描二维码
随时随地手机看文章
I know this is starting to look like a half-baked tutorial in assembly, but there's actually a reason behind my madness. Namely, solving as many problems as possible before switching to Protected mode etc. will lessen the confusion a great deal.
This example prints a string and the contents of a memory location (which is the first letter of the string in video memory). It is meant to demonstrate printing to screen in text mode without using BIOS, as well as converting hex so it can be displayed -- so we can check register and memory values.
A stack is included, but left unused.
;===================================== ; 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 ;==================================