Assembly 我的汇编函数打印一些字符串,但不打印其他字符串

Assembly 我的汇编函数打印一些字符串,但不打印其他字符串,assembly,printing,x86-16,bootloader,bios,Assembly,Printing,X86 16,Bootloader,Bios,我正在开发一个简单的裸机操作系统,我的字符串打印功能只适用于某些字符串,如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

我正在开发一个简单的裸机操作系统,我的字符串打印功能只适用于某些字符串,如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
printlib.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

BIOS将始终在引导扇区的第一个字节开始执行,在您的情况下,该字节似乎是字符串,因此您正在执行数据。事实上,你放在一个名为main的标签上并不影响这一点;没人看它。这可能是因为您的Hello world字符串恰好对应于不会完全破坏一切的指令

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


此外,您的ORG指令和ds段之间存在不一致。引导扇区将在线性地址0x7c00处加载。您可以将段:偏移形式视为0000:7c00或07c0:0000,或者如果您真的需要,也可以将两者之间的其他方式视为0000:7c00或07c0:0000。因此,要访问引导扇区中的数据,您需要使用零加载ds并使用[ORG 0x7c00],或者使用0x07c0加载ds并使用[ORG 0]。但是,您的代码混合了这两者。

BIOS将始终从引导扇区的第一个字节开始执行,在您的情况下,该字节似乎是字符串,因此您正在执行数据。事实上,你放在一个名为main的标签上并不影响这一点;没人看它。这可能是因为您的Hello world字符串恰好对应于不会完全破坏一切的指令

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


此外,您的ORG指令和ds段之间存在不一致。引导扇区将在线性地址0x7c00处加载。您可以将段:偏移形式视为0000:7c00或07c0:0000,或者如果您真的需要,也可以将两者之间的其他方式视为0000:7c00或07c0:0000。因此,要访问引导扇区中的数据,您需要使用零加载ds并使用[ORG 0x7c00],或者使用0x07c0加载ds并使用[ORG 0]。但是,您的代码混合了这两种功能。

按F1键获取帮助不起作用,BIOS提供INT 10h功能。如果您使用BIOS,我不确定它是否符合裸机条件。基本上是将DB作为代码执行的副本。在引导加载程序中也是同样的问题。哦,您还应该初始化堆栈段和堆栈指针,因为您在int、call、ret等许多位置使用堆栈。按F1键获取帮助无效,BIOS提供INT 10h功能,如果你使用BIOS,我不确定它是否符合裸机的条件。基本上是将DB放在代码执行的地方的重复。在引导加载程序中也是同样的问题。哦,您还应该初始化堆栈段和堆栈指针,因为您在int、call和ret的许多位置使用堆栈。将var放在末尾似乎可以解决它,谢谢将var放在末尾似乎可以解决它,谢谢