【问题标题】:String printer doesn't print newlines字符串打印机不打印换行符
【发布时间】:2019-07-03 17:25:46
【问题描述】:

我正在尝试编写一个简单的操作系统,但无法将十六进制数字转换为字符串。我写了一个字符串打印机,如果我在一些预定义的字符串上调用它,它工作正常。但是在将十六进制数字转换为字符串后,它会打印数字,但下一次调用打印机会在同一行打印所有内容,在某些设置中甚至会打印奇怪的字符。

我使用 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

【问题讨论】:

  • 你没有 NUL 终止你的 newLine 字符串。它应该是 db 0xa, 0xd, 0x0 。最终结果是打印 0x0a、0x0d 之后内存中的内容,这就是您看到的垃圾。
  • 哦,现在它工作得多么愚蠢。但这实际上只是一种解决方法。最初我将 0xa, 0xd, 0 放在 hexParser.asm 文件末尾的“输出”变量后面。在没有“换行符打印”的情况下执行此操作会生成以下输出:Hello, World!\n0xde3fBye Bye!\n这是一个测试\n 现在数字和再见消息在同一行,我不明白为什么会这样.
  • NASM 仅处理反引号内的 C 样式转义序列,而不是单引号或双引号。 nasm.us/doc/nasmdoc3.html#section-3.4.2 所以如果你想使用foo\n,你必须把它放在反引号里面。
  • 抱歉,这是个误会。我是新来的,在这个评论编辑器中发布代码不允许我在不同的行上输入和写东西。 “\n”转义序列仅代表不同的代码行......我实际上并没有在我的汇编文件中编写它们。如果我不在这里写但在“回答你的问题”部分,也许它会起作用......?
  • 顺便说一句,整个 determineValue 例程可以替换为 cmp ax, 10 jae hexdigit add ax, '0' ret hexdigit: add ax, 'a' - 10 ret

标签: assembly x86 nasm x86-16 bootloader


【解决方案1】:

如 cmets 中所述,您应该零终止 newLine 消息。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2023-03-17
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    相关资源
    最近更新 更多