字符串打印机不打印换行符

时间:2019-07-03 17:25:46

标签: assembly x86 nasm x86-16 bootloader

我正在尝试编写一个简单的OS,但无法将十六进制数转换为字符串。我写了一个stringprinter,如果我在一些预定义的字符串上调用它,则可以正常工作。但是,在将十六进制数字转换为字符串后,它将打印数字,但是对打印机的下一次调用将在同一行上以及在某些设置中甚至将奇怪的字符都打印出来。

我正在使用NASM生成代码,并使用Bochs来模拟x86 CPU。

[org 0x7c00] ;tell nasm add the adress, specified by org to the relative adresses of the code


mov bx, helloMsg
call stringPrinter
mov dx, 0xde3f
call hexPrinter
mov bx, byeMsg
call stringPrinter
mov bx, newLine
call stringPrinter
mov bx, testMsg
call stringPrinter
jmp end


%include "src/asm/printer.asm"
%include "src/asm/hexParser.asm"

helloMsg:
    db 'Hello, World!', 0xa, 0xd , 0
byeMsg:
    db 'Bye Bye!', 0xa, 0xd, 0

testMsg:
    db 'this is a test', 0xa, 0xd, 0

newLine:
    db 0xa, 0xd

end:
jmp $

times 510-($-$$) db 0 ; pad with zeros until the 510th byte of the sector is reached

dw 0xaa55



stringPrinter:
    pusha
    mov ah,0x0e ; tele output
    start:
        mov al, [bx]
        cmp al, 0x0
        je stop
        int 0x10 ; interupt 10 for screen printing
        inc bx
        jmp start
    stop:
    popa
    ret

charPrinter:
    push ax
    mov ah,0x0e ; tele output
    mov al, bl
    int 0x10
    mov al, 0xa
    int 0x10
    mov al, 0xd
    int 0x10
    pop ax
    ret

hexPrinter:
    pusha
    call hexToString
    mov bx, ax
    call stringPrinter
    popa
    ret



hexToString:
    push bx
    push dx
    mov bx, output
    mov ax, dx
    shr ax, 12
    call determineValue
    add bx, 2
    mov [bx], ax

    mov ax, dx
    and ax, 0x0f00
    shr ax, 8
    call determineValue
    inc bx
    mov [bx], ax

    mov ax, dx
    and ax, 0x00f0
    shr ax, 4
    call determineValue
    inc bx
    mov [bx], ax

    mov ax, dx
    and ax, 0x000f
    call determineValue
    inc bx
    mov [bx], ax

    mov ax, output
    pop dx
    pop bx
    ret

determineValue:
    cmp ax, 0x0
    je zeroDigit
    cmp ax, 0x1
    je oneDigit
    cmp ax, 0x2
    je twoDigit
    cmp ax, 0x3
    je threeDigit
    cmp ax, 0x4
    je fourDigit
    cmp ax, 0x5
    je fiveDigit
    cmp ax, 0x6
    je sixDigit
    cmp ax, 0x7
    je sevenDigit
    cmp ax, 0x8
    je eightDigit
    cmp ax, 0x9
    je nineDigit
    cmp ax, 0xa
    je aDigit
    cmp ax, 0xb
    je bDigit
    cmp ax, 0xc
    je cDigit
    cmp ax, 0xd
    je dDigit
    cmp ax, 0xe
    je eDigit
    cmp ax, 0xf
    je fDigit

    zeroDigit:
        mov ax, '0'
        ret
    oneDigit:
        mov ax, '1'
        ret
    twoDigit:
        mov ax, '2'
        ret
    threeDigit:
        mov ax, '3'
        ret
    fourDigit:
        mov ax, '4'
        ret
    fiveDigit:
        mov ax, '5'
        ret
    sixDigit:
        mov ax, '6'
        ret
    sevenDigit:
        mov ax, '7'
        ret
    eightDigit:
        mov ax, '8'
        ret
    nineDigit:
        mov ax, '9'
        ret
    aDigit:
        mov ax, 'a'
        ret
    bDigit:
        mov ax, 'b'
        ret
    cDigit:
        mov ax, 'c'
        ret
    dDigit:
        mov ax, 'd'
        ret
    eDigit:
        mov ax, 'e'
        ret
    fDigit:
        mov ax, 'f'
        ret

output:
    db '0x0000' , 0

1 个答案:

答案 0 :(得分:2)

如评论中所述,您应将新行消息零终止。

  

号码和再见消息现在都在同一行,我不明白为什么会这样。

您需要输出换行符才能在下一行上显示下一条消息。在对hexPrinter的调用之后,使用newLine添加对stringPrinter的调用,如下所示:

mov dx, 0xde3f
call hexPrinter
mov bx, newLine
call stringPrinter

或更改hexPrinter的output变量以包含换行符,如下所示:

output:
    db '0x0000', 13, 10, 0