使用FASM以实模式打印字符串

时间:2018-06-10 20:18:06

标签: assembly x86-16 bootloader fasm real-mode

我试图调用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

我失踪了什么?

1 个答案:

答案 0 :(得分:0)

FASM可以直接生成二进制文件和可执行文件。事实上,只有当您想要将代码与某些高级语言一起使用时,才需要使用带有目标文件和链接器的FASM。

实际上,FASM的这个属性以及它的高度可移植性使得FASM成为操作系统开发人员最喜欢的汇编程序。

此外,BIOS会将段寄存器设置为0并将SP设置为某个合理的值,因此您根本不需要设置它们。

这是您的代码,从不需要的部分剥离并使用适当的指令(mGetDataTable):

DataSet dsData = new DataSet();

编译后,您将直接获得正确编译的二进制文件:boot.asm;

以下是运行引导扇区的最小命令:

        format binary as "bin"
        use16
        org     7c00h

boot:
        cld                     ; Clear direction flag

        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   ; don't use ":" for the data definitions.

        times 510 - ($-$$) db 0
        dw 0xAA55

请注意,您可以直接将二进制文件提供给qemu模拟器,而无需创建特殊的boot.bin文件。