baby steps #4 - non-BIOS print
Posted: Wed May 22, 2002 12:25 am
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 pmode 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.
I added a stack, but didn't end up using it. However, I just left it in because it will probably get used soon.
;=====================================
; 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 512-($-$$) db 0
;==================================
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.
I added a stack, but didn't end up using it. However, I just left it in because it will probably get used soon.
;=====================================
; 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 512-($-$$) db 0
;==================================