Assembly 使用FASM以实模式打印字符串
我试图调用bios10h中断函数0Eh(电传输出)在实模式下打印字符串(使用QEMU测试)。在NASM中,我没有问题,程序正确打印字符串:Assembly 使用FASM以实模式打印字符串,assembly,x86-16,bootloader,fasm,real-mode,Assembly,X86 16,Bootloader,Fasm,Real Mode,我试图调用bios10h中断函数0Eh(电传输出)在实模式下打印字符串(使用QEMU测试)。在NASM中,我没有问题,程序正确打印字符串: bits 16 ; Use 16 bit code section .text boot: xor ax, ax ; Clear AX register mov ds, ax ; Clear DS re
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
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
我按以下顺序生成软盘映像:
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中,强调文本无法正确打印字符串:
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
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可以直接生成二进制文件和可执行文件。事实上,只有当您希望将代码与某种高级语言结合使用时,才需要将FASM与对象文件和链接器一起使用 事实上,FASM的这一特性,加上它的高度可移植性,使得FASM成为操作系统开发人员最喜爱的汇编程序 此外,BIOS会将段寄存器设置为0,并将SP设置为某个合理的值,因此您根本不需要设置它们 这是您的代码,从不需要的部分剥离出来,并带有正确的指令(
boot.asm
):
编译后,您将直接得到一个正确编译的二进制文件:boot.bin
以下是运行引导扇区所需的最少命令:
$fasm boot.asm
$qemu-system-x86_64 -drive format=raw,media=disk,if=floppy,file=./boot.bin
请注意,您可以直接将二进制文件馈送到qemu emulator,而无需创建特殊的
floppy.img
文件。在您的FASM代码中使用org 0x7c00
,并从链接器命令中删除-Ttext=0x7c00
,因为FASM不同于NASM不输出重定位条目,因此LD没有任何地址需要修复。告诉FASM使用org 0x7c00
而不是org 0x0
可以让FASM从一开始就输出正确的地址。如果您设置了SS,您也应该设置SP,以便SS:SP指向内存中不会干扰代码操作的区域。谢谢您的回答!指出int 0x10/AH=0xE需要更多参数,包括页面编号的BH/BL和图形模式下的颜色。因此,最好是mov bx,0007h
。使用test al,al
根据寄存器值设置标志。缺少DS设置。BIOS不一定有DS=ES=0,因此您应该xor ax,ax
/mov DS,ax
,如中所示。(lodsb
使用DS:SI,因此您可以为该特定程序保留未设置的ES。)