Assembly Int 10,ah 0eh在引导加载程序中给出错误的输出

Assembly Int 10,ah 0eh在引导加载程序中给出错误的输出,assembly,x86,nasm,x86-16,bootloader,Assembly,X86,Nasm,X86 16,Bootloader,我正在尝试编写自己的操作系统,我需要一些print_string func,它将以sI格式打印字符串,如下所示 print_string: Pusha mov ah,0Eh .repeat: lodsb cmp al,0 je .done int 10h Jmp .repeat .done: Popa Ret 但是输出在 mov si,Msg call print_string 就像Wn=Wn= 虽然

我正在尝试编写自己的操作系统,我需要一些print_string func,它将以sI格式打印字符串,如下所示

print_string:
    Pusha
    mov ah,0Eh

    .repeat:
    lodsb
    cmp al,0
    je .done
    int 10h
    Jmp .repeat

    .done:
    Popa
    Ret
但是输出在

mov si,Msg
call print_string
就像Wn=Wn=


虽然Msg是“hello”

这不是一个最小的完整示例,但这个问题非常常见。即使没有看到代码的其余部分,我猜处理器(或模拟处理器)在启动时使用的段与汇编代码使用的偏移量不匹配


对于16位,有许多指向同一物理内存地址的段和偏移的组合。BIOSes最常用的是0x07c0:0x0000和0x0000:0x0000。(0x07c0 Sry我放弃写REST这不是一个。无论如何,你可能设置了
DS
错误,如果有的话。@Jester我怎么能设置DS呢?如果你想创建x86操作系统,你应该知道什么是段:x86 CPU的16位实模式下的偏移寻址,你应该知道哪些寄存器可用,为什么
lodsb
隐式使用
ds
,甚至可以重写它以使用不同的段寄存器,以及x86机器通电后内存映射的外观,即可以将数据放在何处,以及要将段寄存器设置为哪些值等等。在所有这些方面,您应该已经了解x86汇编基础知识,即ode>MOV Sreg,r/m16MOV指令的变体。使用一些书籍/教程?一旦您学习了一些x86汇编基础知识,就有了合理的操作系统开发资源(或更像操作系统开发基础知识):…如果您真的喜欢操作系统开发,在学习这些基础知识之后(可能需要几个月或几年),你可能想检查一些真正的操作系统,如linux或BSD,源代码,他们的开发人员正在研究什么,他们正在试图解决什么样的问题。在这样的社区中工作几年后,你可能会做出有意义的贡献。我测试了它,它工作得很好,但我找到了另一种方法,不管怎样,我是marki将此作为已批准的工作答案,以便其他有此问题的人可以解决此问题。我将仔细设置ds
; Create bootloader with: nasm -f bin boot.asm -o boot.bin
; To test in QEMU use:    qemu-system-i386 -fda boot.bin 
org 0x7c00
main:
    xor ax, ax          ; XOR register with itself zeroes the register
    mov ds, ax          ; We want DS:ORG to be 0x0000:0x7c00
    cld                 ; Forward direction for string instructions like LODSB

    mov si,Msg
    call print_string   ; Print the message

    ; This is a preferred way to do an infinite loop but
    ; you could also do: JMP $. This prevents falling through
    ; the code below and off to memory we don't intend to execute
    cli
.endloop:
    hlt
    loop .endloop

print_string:
    Pusha
    mov ah,0Eh
    xor bx,bx          ; Ensure we are writing to page 0
                       ; XOR register with itself zeroes the register
    .repeat:
    lodsb
    cmp al,0
    je .done
    int 10h
    Jmp .repeat

    .done:
    Popa
    Ret

; Place data after the code but before the boot signature.
Msg db "hello",0            ; Nul terminated string

times 510 - ($ - $$) db 0   ; padding with 0 at the end
dw 0xAA55                   ; PC boot signature
org 0x0000
main:
    mov ax, 0x07c0
    mov ds, ax          ; We want DS:ORG to be 0x07c0:0x0000
    cld                 ; Forward direction for string instructions like LODSB