Hi :)

I'm writing a basic 2 stage bootloader (I actually do plan for it to work, it's not just a hello world loader) and I've migrated to nasm. I find it much easier to use, etc. etc.

Anyway; I'm using the times directive to get the program to 512 bytes, and in all the examples I've seen about boot sector programs, they always have it like this:

times	510-($-$$)	db	0

(it's 510 to account for the boot signature).

Anyway, that's exactle how I have it. I've tried org'ing to different locations ([org 0] was interesting, I got a bunch of S characters printed in an infinite loop) and none have helped.

I've read the nasm manual on times; but it didn't help. I'm having to change the number from 510 to get it to stay at 512 bytes every time I add new code, and it's getting annoying because I have to compile the program twice so that I can change it.

Anyway, what I don't understand is why the times instruction never works for me, but it seems to work when I compile other people's code. I tried combining my include files into one file, and making sure the times and boot signature were at the end of the data segment, but it didn't work.

Here's the main file; tell me if you need more

;=============================================================================;
; stage1.asm: stage1, load and initialize stage2                              ;
;=============================================================================;

;=============================================================================;
[bits	16]
[org 0x7c00]
jmp start
%include	"../include/rmode/diskio.inc" ; real mode disk access (int 13h)
%include	"../include/rmode/scrnio.inc" ; real mode screen i/o (int 10h)
;=============================================================================;

section	.text
;=============================================================================;
	global	start
; start: initialize self, reset the disk and try to load stage2
start:
	xor ax, ax ; Zero ax
	mov ds, ax ; ds = 0
	mov ss, ax ; ss = 0
	mov sp, 0x9c00 ; Place the stack pointer 200h past [cs:0]

	; First, grab the boot disk that the BIOS puts in dl
	mov byte[bootd], dl
	
	print 'stage1 loaded, searching for stage2...', 0
	call findStage2 ; Find stage 2
	cmp ax, 0 ; Check return value
	mov word[integer], ax
	jne _error ; Uh-oh

	print ' done.', 13, 10, 'stage2  found, loading...', 0
	call loadStage2 ; Load stage2 into memory at 0x7e00
	cmp ax, 0 ; Check stage2 was loaded properly
	mov word[integer], ax
	jne _error
	
	print ' done.', 13, 10, 'stage2 loaded, executing...', 0
	; Set register state
	mov dl, byte[bootd] ; stage2 wants boot disk, put it back in dl
	xor ax, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	print ' Bye!', 13, 10, 0
	jmp cseg:off ; Jump to stage2
	print 'Unable to jump to stage 2!'
	jmp $
;-----------------------------------------------------------------------------;
; findStage2: search for the stage2 file in the next 30 KiB of the disk
findStage2:
	ret
;-----------------------------------------------------------------------------;
loadStage2:
	ret
;-----------------------------------------------------------------------------;
_error:
	print 'error: ax = ', 0
	call intprint
	print 10, 13, 0
	ret
;=============================================================================;

section	.data
;=============================================================================;
dseg	db	0x10	; data segment
cseg	db	8		; code segment
off		db	0x7e00  ; offset of stage2 in memory
bootd	db	0		; boot disk
		times	510-($-$$)	db	0
		dw	0xaa55
;=============================================================================;

Recommended Answers

All 4 Replies

($ - $$) gives you the offset in the current section, that is, in .data. The way your code is written, the .data section will occupy whole 512 bytes.

You need a simple

times (510 - $) db 0

($ - $$) gives you the offset in the current section, that is, in .data. The way your code is written, the .data section will occupy whole 512 bytes.

You need a simple

times (510 - $) db 0

Oh, thanks.

($ - $$) gives you the offset in the current section, that is, in .data. The way your code is written, the .data section will occupy whole 512 bytes.

You need a simple

times (510 - $) db 0

I have changed that, but now nasm complains that times is not being supplied a constant value:

error: non-constant argument supplied to TIMES

I'm not understanding how this:

section .data
;=============================================================================;
dseg	db	0x10	; data segment
cseg	db	8		; code segment
off		db	0x7e00  ; offset of stage2 in memory
bootd	db	0		; boot disk
		times	(510 - $)	db	0
		dw	0xaa55
;=============================================================================;

is not a constant value.

What can I try to do to get this to work?

Hm, I got it to work by allowing nasm to section everything itself, so I basically removed all sectioning stuff and then used

times 510 - ($ - $$) db 0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.