Quick review: (1) boot sector loaded by BIOS is 512 bytes (2) the code in the boot sector of the disk is loaded by the BIOS at 0000:7c00 (3) machine starts in real mode (4) be aware that the CPU is being interrupted unless you CLI
**************
Many (but not all) BIOS interrupts expect DS to be filled with a real-mode segment value. This is why many BIOS interrupts won't work in protected mode. So if you want to use int 10h/ah=0eh to print to the screen, then you need to make sure that your seg:offset for the characters to print is correct.
It doesn't matter if you use 0000:7c00 or 07c0:0000, but if you use ORG, you need to be aware of what's happening.
;------------------------
mov ax, 0x07c0
mov ds, ax
mov si, msg
ch_loop:lodsb
or al,al ;zero=end of str
jz hang ;get out
mov ah,$0e
int $10
jmp ch_loop
hang:
jmp hang
msg db 'Welcome to Macintosh', 13, 10, 0
times 512-($-$$) db 0
;------------------------
Here's the ORG version. Note that you still need to tell DS what to be
;------------------------
[ORG 0x7c00]
xor ax, ax ;make it zero
mov ds, ax
mov si, msg
ch_loop:lodsb
or al,al ;zero=end of str
jz hang ;get out
mov ah,$0e
int $10
jmp ch_loop
hang:
jmp hang
msg db 'Welcome to Macintosh', 13, 10, 0
times 512-($-$$) db 0
;------------------------
New topic: Typically 'procedures' are separated from the code using CALL/RET like he following
;------------------------
[ORG 0x7c00]
xor ax, ax ;make it zero
mov ds, ax
mov si, msg
call bios_print
hang:
jmp hang
msg db 'Welcome to Macintosh', 13, 10, 0
bios_print:
lodsb
or al,al ;zero=end of str
jz done ;get out
mov ah,$0e
int $10
jmp bios_print
done:
ret
times 512-($-$$) db 0
;------------------------
For some inexplicable reason, loading SI *then* jumping to the procedure lways bugged me. Fortunately for psychos like me NASM's macros let you retend that you are passing a parameter (macro definition has to go before t's being called).
;------------------------
%macro BiosPrint 1
mov si, word %1
ch_loop:lodsb
or al,al ;zero=end of str
jz done ;get out
mov ah,$0e
int $10
jmp ch_loop
done:
%endmacro
[ORG 0x7c00]
xor ax, ax ;make it zero
mov ds, ax
BiosPrint msg
hang:
jmp hang
msg db 'Welcome to Macintosh', 13, 10, 0
times 512-($-$$) db 0
;------------------------
And in case your code is becoming long and unreadable, you can break it up into ifferent files, then include the files at the beginning of your main code. Like o:
;------------------------
jmp main
%include "othercode.inc"
main:
;... rest of your code here
;------------------------
baby steps #2 - bios print
Re:baby steps #2 - bios print
Thanks crazybuddha,I for one found them interesting and look forward to the next installment ;D
\\\///
(@@)
ASHLEY4.
\\\///
(@@)
ASHLEY4.
Re:baby steps #2 - bios print
I'm a newbie OS developer (and new to asm too ;D), but reading the nasm docu I believe it would be better to use macro-local lables, so you can use the macro more than once:
; Define macro with one Argument
%macro BiosPrint 1
; Set si to string address
mov si, word %1
%%ch_loop:
; Load byte-string from si (esi in 32 bit mode)
lodsb
; Check for null byte
or al, al
jz done
; Invoke bios-interrupt
mov ah, 0x0E
int 0x10
jmp %%ch_loop
%%done:
%endmacro
Have fun,
TriDix
Btw. Nice snippets crazybuddha!
; Define macro with one Argument
%macro BiosPrint 1
; Set si to string address
mov si, word %1
%%ch_loop:
; Load byte-string from si (esi in 32 bit mode)
lodsb
; Check for null byte
or al, al
jz done
; Invoke bios-interrupt
mov ah, 0x0E
int 0x10
jmp %%ch_loop
%%done:
%endmacro
Have fun,
TriDix
Btw. Nice snippets crazybuddha!