所以我开始学习汇编,并且正在用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
问题是只能使单个字符不是字符串。
答案 0 :(得分:3)
PC的ROM BIOS提供一组视频服务,通过中断10h调用,包括一些将字符打印到字符串。可以找到here的综合文档。
您似乎已经发现了服务0Eh,它将当前字符位置的单个字符写入屏幕并提升字符位置。这会将屏幕视为电传打字机(TTY),并且可以很容易地在屏幕上输出。
(至少,看起来就像你试图调用服务0Eh。你的代码不正确。你有mov ah, eoh
,这是不正确的。{{1} }不是十六进制值,即使这是0的拼写错误,你也可以反转半字节。它应该是o
。)
如果要打印字符串(多个字符),基本上有两个选项:
您可以迭代地调用像0Eh这样的服务,每次都会在字符串中写入一个字符。这方面的一个示例实现是:
mov ah, 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
指向的字符串中的字符,直到达到0(NUL字符),表示字符串的结尾(标准的C风格NUL终止字符串)。
但是,这种一次打印一个字符的方法相对较慢。相反,人们通常更喜欢......
使用service 1300h或1301h立即打印整个字符串。不同之处在于服务1301h在打印字符串之后使光标前进,而服务1300h不改变光标。否则,他们是一样的。
这些服务的参数记录在上面的链接中;为方便起见,在此重印:
SI
== 1300h / 1301h AX
==视频属性(在文字模式下,指定前景色和背景色)BL
==视频页面(通常为0)BH
==字符串长度CX
/ DL
==字符串 DH
==字符串开头的地址
显然,这需要事先知道字符串的长度,并将其作为ES:BP
寄存器中的参数传递。该字符串由CX
指向。
在您的情况下,要打印“FILE SYSTEM”,您将在DATA段中声明包含此字符串的字符数组,然后执行以下操作:
ES:BP
MyString DB "FILE SYSTEM"