【问题标题】:How to add text to OS written in assembly如何将文本添加到用汇编编写的操作系统
【发布时间】:2017-05-28 19:43:23
【问题描述】:

所以我开始学习汇编,并正在使用 FASM 编写一个简单的操作系统。我有一个带有灰色顶栏和光标的蓝屏,但无法让文本出现在一行上。在第一行我想让它说“文件系统”,然后在其他行我想要其他东西。我把代码放在这里:

mov ax, 9ch
mov ss, ax
mov sp, 4096d
mov ax, 7c0h
mov ds, ax
;----------------


;this sets blue to background
mov ah, 09h
mov cx, 1000h
mov al, 20h
mov bl, 17h
int 10h
;end of blue

;start of gray top
mov ah, 09h
mov cx, 80d
mov al, 20h
mov bl, 87h
int 10h
;end of gray
;top bar






;end of top bar
;define mouse
mov ah, 01h
mov cx, 07h
int 10h

mov bl, 5h
mov cl, 5h


_mouser:
mov ah, 02h
mov dl, bl
mov dh, cl
int 10h

mov ah, 00h
int 16h

cmp al, 77h
je _up
cmp al, 73h
je _down
cmp al, 61h
je _left
cmp al, 64h
je _right
cmp al, 20h
je _click
jmp _mouser



_click:
mov ah, 0eh
mov al, 0b2h
int 10h
jmp _mouser

_up:
cmp cl, 0h
je _mouser
sub cl, 1h
jmp _mouser

_down:
cmp cl, 24d
je _mouser
add cl, 1h
jmp _mouser

_left:
cmp bl, 0h
je _mouser
sub bl, 1h
jmp _mouser

_right:
cmp bl, 79d
je _mouser
add bl, 1h
jmp _mouser



;----------------
times 510-($-$$) db 0
dw 0xAA55

我试过了

mov ah, eoh
mov al, 'F'
int 10h

问题是只能使单个字符而不是字符串。

【问题讨论】:

  • mov ah, 0eh; mov al, 'F'; int 10h 应该会更好。
  • 是的,我知道这是一个字符,但我需要创建一个字符串
  • 花点时间阅读 wiki osdev.org
  • 在循环中重复所有字符以组成一个字符串。
  • 创建一个操作系统,但使用 BIOS 进行文本模式输出...如果这不是学习的教育努力,那将是完全错误的。再说一次,至少检查 BIOS 文档以查看可用的服务是预期的,并且首先学习 x86 汇编也有帮助。并且以经典的 VGA 文本模式直接写入 VRAM 非常简单,所以你也可以检查一下。

标签: assembly operating-system fasm


【解决方案1】:

PC 的 ROM BIOS 提供一组视频服务,通过中断 10h 调用,包括一些将字符打印到字符串的服务。他们的综合文档可以在here找到。

您似乎已经发现了服务 0Eh,它在当前字符位置将单个字符写入屏幕并推进字符位置。这会将屏幕视为电传打字机 (TTY),并且可以很容易地在屏幕上获得输出。

(至少,它看起来就像你试图调用服务 0Eh。你的代码不正确。你有 mov ah, eoh,这是不正确的。o 不是一个十六进制值,即使是 0 的拼写错误,您也可以颠倒半字节。应该是 mov ah, 0Eh。)

如果你想打印一个字符串(多个字符),你基本上有两种选择:

  1. 您可以迭代调用 0Eh 之类的服务,每次将单个字符写入字符串。一个示例实现是:

        mov  ah, 0Eh             ; service 0Eh: print char as TTY
    .PrintNextChar:
        mov  al, BYTE PTR [si]   ; get next character in string, pointed to by SI
        inc  si                  ; increment pointer
        test al, al              ; is character == 0 (end-of-string)?
        je   .Done
        int  10h
        jmp  .PrintNextChar
    .Done
    

    这会打印SI 指向的字符串中的字符,直到它到达一个 0(NUL 字符),这表示字符串的结束(一个标准的 C 样式 NUL 终止的字符串)。

    但是,这种一次打印一个字符的方法相对较慢。相反,人们通常更喜欢……

  2. 使用服务 1300h 或 1301h 一次打印整个字符串。不同之处在于服务 1301h 在打印字符串后使光标前进,而服务 1300h 不更改光标。否则,它们是相同的。

    这些服务的参数记录在上面的链接中;为方便起见,在此转载:

    • AX == 1300h/1301h
    • BL == video 属性(在文本模式下,指定前景色和背景色)
    • BH == 视频页面(通常为 0)
    • CX == 字符串长度
    • DL/DH == 字符串起始位置的列/行
    • ES:BP == 字符串开头的地址

    显然这需要你事先知道字符串的长度,并将其作为参数传入CX寄存器。该字符串由ES:BP 指向。

    在您的情况下,要打印“文件系统”,您将在包含此字符串的 DATA 段中声明一个字符数组,然后执行以下操作:

    MyString DB "FILE SYSTEM"
    
    mov  ax, ds
    mov  es, ax          ; set ES == DS
    mov  bp, MyString
    mov  cx, 11          ; length of string (number of chars)
    mov  bx, 07h         ; foreground & background color (white on black)
    xor  dx, dx          ; starting position (top-left)
    mov  ax, 1301h       ; service 1301h: print string and update cursor
    int  10h
    

【讨论】:

    猜你喜欢
    • 2012-07-07
    • 2013-02-12
    • 2014-05-24
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2011-10-15
    • 2021-10-28
    • 2022-10-15
    相关资源
    最近更新 更多