【发布时间】:2018-06-10 20:18:06
【问题描述】:
我正在尝试调用 BIOS 10h 中断函数 0Eh(电传输出)以在实模式下打印字符串(使用 QEMU 进行测试)。在 NASM 中我没有问题,程序正确打印字符串:
bits 16 ; Use 16 bit code
section .text
boot:
xor ax, ax ; Clear AX register
mov ds, ax ; Clear DS register
mov es, ax ; Clear ES register
mov ss, ax ; Clear SS register
mov si, hello ; Set SI to string
mov ah, 0x0E ; Set function
.loop:
lodsb ; Store character into AL
or al, al ; Check for NULL end
jz halt ; On NULL end
int 0x10 ; Call 10h interrupt
jmp .loop ; Continue with next character
halt:
cli
hlt
hello: db "Hello, World!", 0
times 510 - ($-$$) db 0
dw 0xAA55
我按照以下命令制作软盘映像:
nasm -f elf64 boot.asm -o boot.o
ld -Ttext 0x7c00 boot.o -o boot.out
objcopy -O binary -j .text boot.out boot.bin
dd if=/dev/zero of=floppy.img bs=1024 count=720
dd if=boot.bin of=floppy.img conv=notrunc
但在 FASM强调的文本不能正确打印字符串:
format elf64
use16
section '.text'
org 0x0
boot:
cld ; Clear direction flag
xor ax, ax ; Clear AX register
mov ds, ax ; Clear DS register
mov es, ax ; Clear ES register
mov ss, ax ; Clear SS register
mov si, hello ; Set SI to string
mov ah, 0x0E ; Set function
puts:
lodsb ; Store character into AL
or al, al ; Check for NULL end
jz halt ; On NULL end
int 0x10 ; Call 10h interrupt
jmp puts ; Continue with next character
halt:
cli
hlt
hello: db "Hello, World!", 0
times 510 - ($-$$) db 0
dw 0xAA55
并生成软盘映像:
fasm boot.asm boot.o
ld -Ttext 0x7c00 boot.o -o boot.out
objcopy -O binary -j .text boot.out boot.bin
dd if=/dev/zero of=floppy.img bs=1024 count=720
dd if=boot.bin of=floppy.img conv=notrunc
我错过了什么?
【问题讨论】:
-
在您的 FASM 代码中使用
org 0x7c00并从链接器命令中删除-Ttext=0x7c00 -
-Ttext=0x7c00不对 FASM 生成的 ELF 对象做任何事情,因为 FASM 与 NASM 不同,它不输出重定位条目,因此 LD 没有任何要修复的地址。告诉 FASM 使用org 0x7c00而不是org 0x0会让 FASM 输出正确的地址。 -
如果您设置了 SS,您也应该设置 SP,以便 SS:SP 指向不会干扰代码操作的内存区域。
-
感谢您的回答!
标签: assembly x86-16 bootloader fasm real-mode