Reputation: 184
I've got two NASM files for an OS of mine I'm writing in assembly, and I'm almost 100% positive they work, but I can't tell, because I don't know exactly how to compile them. I know how to use the commands nasm -f bin boot.asm -o boot.bin
and the cat boot.bin > image.hdd
, but now I've got two files to use, and I don't know how to link them. I've tried compiling the two of them into separate .bin files, and then use cat boot.bin other.bin > image.hdd
but when I try to open it with VirtualBox (I use that to test my OS things) it wont let me.
Here's the code I have in my two assembly files if you need to take a look at them
;--------------------------------------------
; 'boot.asm'
; loaded from BIOS
[org 0x7C00]
[bits 16]
;--------------------------------------------
main:
mov ah, 0x0E ; print function
mov al, '.' ; ascii char
int 0x10 ; IO int
resetdisk:
mov ah, 0x00 ; reset function
mov dl, 0x00 ; drive
int 0x13 ; disk int
jc resetdisk
readdisk:
mov bx, 0x8000 ; segment
mov es, bx
mov bx, 0x0000 ; offset
mov ah, 0x02 ; read function
mov al, 0x03 ; sectors
mov ch, 0x00 ; cylinder
mov cl, 0x02 ; sector
mov dh, 0x00 ; head
mov dl, 0x00 ; drive
int 0x13 ; disk int
jc readdisk
db 0eah
dw 00000h ; offset
dw 08000h ; segment
;--------------------------------------------
times 510 - ($ - $$) db 0x00
db 0x55, 0xAA
and
;--------------------------------------------
; 'load.asm'
; loaded from 'boot.asm'
[org 0x8000]
[bits 16]
;--------------------------------------------
main:
mov ah, 0x0E ; print function
mov al, '.' ; ascii char
int 0x10 ; IO int
jmp $ ; hang
SIDE NOTE: I'm on Mac OS X Mountain Lion, so I'm at my wits ends getting help.
Upvotes: 0
Views: 517
Reputation: 7238
Assuming you're using a hard disk instead of a floppy image (image.hdd), you'd first want to change boot.asm like this:
;--------------------------------------------
; 'boot.asm'
; loaded from BIOS
[org 0x7C00]
[bits 16]
;--------------------------------------------
main:
mov ah, 0x0E ; print function
mov al, '.' ; ascii char
int 0x10 ; IO int
resetdisk:
mov ah, 0x00 ; reset function
mov dl, 0x80 ; drive
int 0x13 ; disk int
jc resetdisk
readdisk:
mov bx, 0x8000 ; segment
mov es, bx
mov bx, 0x0000 ; offset
mov ah, 0x02 ; read function
mov al, 0x01 ; sectors
mov ch, 0x00 ; cylinder
mov cl, 0x02 ; sector
mov dh, 0x00 ; head
mov dl, 0x80 ; drive
int 0x13 ; disk int
jc readdisk
db 0eah
dw 00000h ; offset
dw 08000h ; segment
;--------------------------------------------
times 510 - ($ - $$) db 0x00
db 0x55, 0xAA
Note that drive (dl) and sector count (al) where changed before the two int 0x13 calls. Then you'd want to create an image that is a multiple of 512 bytes like this:
$ nasm -f bin boot.asm -o boot.bin
$ nasm -f bin load.asm -o load.bin
$ dd if=/dev/zero of=pad504 bs=1 count=504
$ cat boot.bin load.bin pad504 > image.hdd
The padding is 504 bytes because load.bin is 8 bytes and 512 - 8 = 504. So as you modify load.asm, you'd want to change the command to generate a padding of suitable size with
$ dd if=/dev/zero of=padding bs=1 count=$((512 - $(ls -l load | cut -d ' ' -f 5) % 512))
$ cat boot.bin load.bin padding > image.hdd
Upvotes: 2
Reputation: 3119
What won't Virtualbox "let" you do?
In addition to Scottt's suggestions, I'd point out that you're reading load.bin
to segment 0x8000 offset 0, and jumping to segment 0x8000 offset 0, but load.asm
specifies org 0x8000
. This is not correct. It won't bother you in this rudimentary program, but as soon as you try to print msg
, it'll fail. Unlike an ordinary programming environment, in a boot environment there's no OS to manage your segment registers - you need to keep 'em in order yourself. cs
is set by the far jump (or we're executing some other code altogether!) but ds (etc.) is up to you. A sane ss:sp
wouldn't be a bad idea, either. You don't need this yet, but you will soon.
Upvotes: 1