首页 > 解决方案 > 程序集引导加载程序一直使用“mov ah, 09h”打印 S

问题描述

每次我尝试为我的程序集引导加载程序添加颜色时,它总是打印“S”,我不知道为什么!

代码:

            BITS 16
    
    start:
        mov ax, 07C0h       ; Set up 4K stack space after this bootloader
        add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
        mov ss, ax
        mov sp, 4096
    
        mov ax, 07C0h       ; Set data segment to where we're loaded
        mov ds, ax
    
    
        ;setting video mode
        mov ah, 00h
      mov al,00h
      int 10h
        ;setting cursor position
        mov ah, 02h  
        mov dh, 10    ;row 
        mov dl, 45     ;column
        int 10h
    
        mov si, text_string ; Put string position into SI
        call print_string   ; Call our string-printing routine
    
        jmp $           ; Jump here - infinite loop!
    
    
        text_string db 'KRIPKE OS', 0
    
    
    print_string:           ; Routine: output string in SI to screen
    mov ah, 09h
    mov bl, 2  ;colour
    mov cx, 1    ;no.of times

.repeat:
    lodsb           ; Get character from string
    cmp al, 0
    je .done    ; If char is zero, end of string
    int 10h         ; Otherwise, print it
    mov ah, 02h
    add dl, 1
    jmp .repeat

.done:
    ret

    
    
        times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
        dw 0xAA55       ; The standard PC boot signature

请帮助我尝试解决此问题。我认为 bl 寄存器可能有问题。我需要在顶部添加 [org 0x7c00] 吗?

输出: K 然后很多空格

标签: assemblyoperating-systemx86-16bootloader

解决方案


BIOS 调用不会更新光标位置,因此int 10h / ah=09h您需要int 10h / ah=02h在打印每个字符后重复您的 ,并增加位置。您当前的代码将mov ah, 02handadd dl, 1放入循环中,但实际上并没有进行第二次int 10h调用。您也必须ah09h每个字符输出调用之前重置。

更好的是,在输出字符之前更新循环中的光标位置。这也意味着您不再需要在调用print_string或进入循环之前设置光标位置。

我会写:

print_string:           ; Routine: output string in SI to screen
    mov dl, 45      ; initial cursor column column
    mov dh, 10      ; row
    mov bl, 2       ; colour
    mov cx, 1       ; no.of times

.repeat:
    mov ah, 02h     ; update cursor position
    int 10h
    inc dl          ; same as `add dl, 1` but smaller 

    lodsb           ; Get character from string
    cmp al, 0
    je .done        ; If char is zero, end of string
    mov ah, 09h     ; Otherwise, print it
    int 10h         


    jmp .repeat

.done:
    ret

为了进一步增强,让调用者print_string设置 的值,dh,dl以便它可以在任何所需的位置打印。也许也bl让调用者也可以选择颜色。


推荐阅读