问题
I'm developing a Hello World kernel and bootloader...I wrote this code but when I try to compile it via NASM It says : "bootloader.asm:30: error: TIMES value -44 is negative".
bootloader.asm:
[BITS 16]
[ORG 0x7C00]
MOV DL, 0x80
MOV DH, 0x0
MOV CH, 0x0
MOV CL, 0x02
MOV BX, 0x1000
MOV ES, BX
MOV BX, 0x0
ReadFloppy:
MOV AH, 0x02
MOV AL, 0x01
INT 0x13
JC ReadFloppy
MOV AX, 0x1000
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
JMP 0x1000:0x0
TIMES 510 - ($ - $$) db 0
DW 0xAA55
kernel.asm:
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
MOV SI, msg
CALL PrintString
JMP $
PrintString:
nextch:
MOV AL, [SI]
OR AL, AL
JZ exit
INT 0x10
INC SI
JMP nextch
RET
exit:
RET
msg db 'Hello world from the kernel!', 13, 10, 0
TIMES 512 - ($ - $$) db 0
I used; nasm -f bin bootloader.asm -o bootloader.bin -p kernel.asm
回答1:
You have a more fundamental problem than your doubled usage of times
: You are using NASM's -p
switch to pre-include the file kernel.asm while building bootloader.asm. Even if you drop one or both times
usages, the kernel will be assembled first and executed first, instead of your loader executing first.
I fixed your example to do what it seems supposed to do: Write the kernel.asm output into the second 512-bytes sector, then in the loader, load that sector from the boot unit and jump to it.
Here's the fixed source, bootloader.asm:
cpu 8086
bits 16
section loader vstart=7C00h start=0
MOV AX, 0x1000
MOV DS, AX
MOV ES, AX
MOV SS, AX
xor sp, sp
MOV DH, 0x0
MOV CH, 0x0
MOV CL, 0x02
xor bx, bx
mov di, 16
ReadFloppy:
dec di
jz .error
MOV AH, 0x02
MOV AL, 0x01
INT 0x13
JC ReadFloppy
JMP 0x1000:0x0
.error:
mov ax, '!' | 0E00h
mov bx, 7
int 10h
.halt:
sti
hlt
jmp .halt
TIMES 510 - ($ - $$) db 0
DW 0xAA55
%include "kernel.asm"
This is kernel.asm:
section kernel vstart=0 follows=loader
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
MOV SI, msg
CALL PrintString
halt:
sti
hlt
jmp halt
PrintString:
nextch:
MOV AL, [SI]
OR AL, AL
JZ exit
INT 0x10
INC SI
JMP nextch
exit:
RET
msg db 'Hello world from the kernel!', 13, 10, 0
TIMES 512 - ($ - $$) db 0
This is how to build and run the entire example:
$ nasm -f bin bootloader.asm -o bootloader.bin && qemu-system-i386 -drive file=bootloader.bin,if=floppy,format=raw,index=0,media=disk
$ nasm -f bin bootloader.asm -o bootloader.bin && qemu-system-i386 -drive file=bootloader.bin,format=raw,index=0,media=disk
Note that I changed the following:
Instead of
org
I used a section directive for the loader, withvstart=7C00h
andstart=0
. This is essentially the same as your original, but fits better with the other section.The kernel is included using the
%include
directive, and is placed after the loader, not before it (like with your-p
use).The file kernel.asm thus does not occur on the NASM command line any longer.
The kernel is put in a separate section, which has
vstart=0
(calculates labels as if that section was loaded at the start of a segment) andfollows=loader
(to correctly place it in the output file as the second sector).In the instruction immediately after setting
ss
I setsp
, as we cannot be sure of the value ofsp
prior to this. Zeroingsp
(withxor
) means the stack starts at the top of the segment, that is out of the way of where we read the kernel sector to.I dropped the
RET
afterJMP nextch
. It was never reached.I changed the halting loop from
JMP $
tosti
\hlt
\jmp
to idle while halting. This means the qemu process won't waste CPU time while running this loop.I dropped your
MOV DL, 0x80
. This allows booting from either a hard disk unit or a diskette; at our entrypoint the ROM-BIOS has initialiseddl
with the unit we're being loaded from.I moved the segments and stack initialisation to before the sector reading. This insures the stack does not overlap with the read destination.
I added a loop counter in
di
for the read attempts. I added an additional branch for if this runs out, which displays an exclamation mark then halts. Retrying the read operation is not wrong, but if it fails permanently then there should be a maximum amount of retries.I dropped setting
fs
andgs
as they are never used.
来源:https://stackoverflow.com/questions/60980527/how-to-solve-bootloader-asm30-error-times-value-44-is-negative-problem-in