可以找到一种用nasm正确打印字符串的方法

发布于 2025-02-03 13:21:31 字数 2227 浏览 2 评论 0原文

我正在编写一个简单的操作系统,该操作系统将所有STDIN(键盘输入)打印到STDOUT(屏幕)。我想在输入之前打印一个欢迎字符串。我正在使用NASM,因为它是可读且易于使用的。

我已经尝试了两种打印字符串的方法:(

假设欢迎定义为db“欢迎使用texteditos!

  1. 使用类似于时, 循环。最初,我使用bx而不是si,因为有几个教程这样做,但是此答案使用si建议,因为bx用于在TTY模式下的页码和颜色。
mov si, welcome
mov ah, 0eh

printWelcome:
    cmp [si], byte 0
    je mainLoop
    mov al, [si]
    int 0x10
    inc si
    jmp printWelcome
  1. 使用int 10H其中ah = 13H。我使用的代码是这样的,尽管我相信我的家用计算机上有原始代码(我现在不在,一旦我回来后会更新此问题)。
    xor ax, ax
    mov es, ax
    xor bh, bh
    mov bp, welcome

    mov ah, 0x13
    mov bl, 0ah ;this was something else I think
    mov al, 1   ;write mode
    mov cx, 56  ;length
    mov dh, 0   ;x
    mov dl, 0   ;y

    int 0x10

这两者在Qemu中都很好。但是,当我将完整代码刻录到USB闪存驱动器上并启动它时,第一种方式在屏幕中间停止之前,在1-2个看不见的字符上打印屏幕,而另一个似乎似乎打印了@< /code>,什么都没有。我的其余代码是键盘输入,双向运行良好。

这是我的操作系统的完整代码:

[org 0x7c00]

jmp short start

db 90h,90h,"TEXTOS",20h,20h

section .text

start:

; First, let's set up the stack
mov bp, 7c00h
mov sp, bp

; Insert either way I used to print the string below

; end print func

mainLoop:
    mov ah, 0    ; get keyboard input
    int 16h
    mov ah, 0eh  ; print char
    int 10h      ; al already has the char to print
    cmp al, 13   ; is char 0dh?
    je newLine
    cmp al, 8    ; is char 08h?
    je backSpace
    jmp mainLoop ; loop

newLine:
    mov al, 10   ; complete \n with 0ah
    int 10h
    jmp mainLoop

backSpace:
    mov al, 32   ; insert space over last char
    int 10h
    mov al, 8    ; then another backspace to go back
    int 10h
    jmp mainLoop

welcome: ; welcome message
    db "Welcome to TextEditOS! Type whatever you want below.", 0dh, 0ah, 0dh, 0ah, 0

times 510-($-$$) db 0
; Boot signature
dw 0xaa55

用于编译和运行的命令:

nasm boot.asm -fbin -oboot.img
qemu-system-x86_64 -drive file=boot.img,format=raw

如上所述,我将找到#2的代码并使用它编辑此问题。我还将尝试上传一些我在真实硬件上获得的gif。

I am writing a simple OS which prints all stdin (keyboard input) to stdout (the screen). I want to print a welcome string before the input. I'm using NASM since it is readable and easy to use.

I've tried two ways to print the string:

(Assume welcome is defined as db "Welcome to TextEditOS! Type whatever you want below.",0dh,0ah,0dh,0ah,0. Remove the 0 for #2.)

  1. Using a loop similar to a while loop. Originally I used bx instead of si since a few tutorials did it that way, but this answer suggested using si since bx is used for the page number and color in TTY mode.
mov si, welcome
mov ah, 0eh

printWelcome:
    cmp [si], byte 0
    je mainLoop
    mov al, [si]
    int 0x10
    inc si
    jmp printWelcome
  1. Using int 10h where ah=13h. The code I used is something like this, though I believe I have the original code on my home computer (I'm away right now, will update this question once I get back).
    xor ax, ax
    mov es, ax
    xor bh, bh
    mov bp, welcome

    mov ah, 0x13
    mov bl, 0ah ;this was something else I think
    mov al, 1   ;write mode
    mov cx, 56  ;length
    mov dh, 0   ;x
    mov dl, 0   ;y

    int 0x10

Both of these work just fine in QEMU. However, when I burn the full code onto a USB flash drive and boot it, the first way prints around 1-2 screens of invisible characters before stopping in the middle of the screen, and the other seems to print an @ and nothing else. The rest of my code, which is the keyboard input, works fine both ways.

Here is the full code for my operating system:

[org 0x7c00]

jmp short start

db 90h,90h,"TEXTOS",20h,20h

section .text

start:

; First, let's set up the stack
mov bp, 7c00h
mov sp, bp

; Insert either way I used to print the string below

; end print func

mainLoop:
    mov ah, 0    ; get keyboard input
    int 16h
    mov ah, 0eh  ; print char
    int 10h      ; al already has the char to print
    cmp al, 13   ; is char 0dh?
    je newLine
    cmp al, 8    ; is char 08h?
    je backSpace
    jmp mainLoop ; loop

newLine:
    mov al, 10   ; complete \n with 0ah
    int 10h
    jmp mainLoop

backSpace:
    mov al, 32   ; insert space over last char
    int 10h
    mov al, 8    ; then another backspace to go back
    int 10h
    jmp mainLoop

welcome: ; welcome message
    db "Welcome to TextEditOS! Type whatever you want below.", 0dh, 0ah, 0dh, 0ah, 0

times 510-($-$) db 0
; Boot signature
dw 0xaa55

Commands used to compile and run:

nasm boot.asm -fbin -oboot.img
qemu-system-x86_64 -drive file=boot.img,format=raw

As said above, I will find the code for #2 and edit this question with it. I will also try to upload some GIFs of what I get on real hardware.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文