首页 > 解决方案 > 我的汇编函数打印一些字符串,但不是其他的

问题描述

我正在开发一个简单的裸机操作系统,我的打印字符串功能仅适用于某些字符串(例如“Hello World”),但不适用于其他字符串(例如“按 F1 寻求帮助”)

[ORG 0x7C00]
msg db "Press F1 for help",0

main:
    mov AH, 00h
    int 16h
    cmp AH, 0x3B
    je help 
    jmp main

help:
    mov si, msg
    call print
    jmp main

; Print library, invoke with "call print" example:
; msg db "Foobar",0
; mov SI, msg
; call print
%include "printlib.inc"
 
return:
    ret

times 510-($-$$) db 0;
db 0x55
db 0xAA

打印库.inc:

print:
    mov ax, 0x07c0
    mov ds, ax
    cld
    jmp .loop
.loop:lodsb
    or al, al ; zero=end or str
    jz .retn   ; get out
    mov ah, 0x0E
    mov bh, 0
    int 0x10
    jmp .loop
.retn:
    ret

标签: assemblyprintingx86-16bootloaderbios

解决方案


BIOS 将始终从引导扇区的第一个字节开始执行,在您的情况下,这似乎是字符串,因此您正在执行数据。(您放入一个名为的标签这一事实main不会影响这一点;什么都看不到它。)可能是您的“Hello world”字符串恰好对应于不会完全破坏所有内容的指令。

尝试将字符串移动到所有代码之后,或者jmp main在它之前插入一个。

此外,您的ORG指令和ds细分之间存在不一致。您的引导扇区被加载到线性地址0x7c00。您可以在段:偏移形式中将其视为0000:7c0007c0:0000(或其他方式,如果您真的想要)。因此,要访问引导扇区中的数据,您要么需要加载ds零并使用[ORG 0x7c00],要么加载ds0x07c0使用[ORG 0]。但是,您的代码将两者混合在一起。


推荐阅读