我的读写字符串函数吐出了%%%,而不是我放入的3个字符
所以我开始写一个“内核”这样说,我正在尝试读取一个字符串并将其打印回我。问题出现在我执行它时,它只是打印3个相同的字符,而不是我在线上写的内容。我的读写字符串函数吐出了%%%,而不是我放入的3个字符
read_string:
call newline
mov si, read_attempt
call print
call newline
push bx
mov ah, 0x03
int 0x10
mov dl, 0
int 0x10
;read 1st char
mov ah, 0x08
int 0x10
mov bl, al
pop bx
;read 2nd char
mov ah, 0x03
int 0x10
add dl, 1
int 0x10
mov ah, 0x08
int 0x10
mov bl, al
pop bx
;read 3rd char
mov ah, 0x03
int 0x10
add dl, 1
int 0x10
mov ah, 0x08
int 0x10
mov bl, al
pop bx
;try to write all 3 chars
call newline
mov si, write_attempt
call print
call newline
push bx
mov al, bl
call printchar
push bx
mov al, bl
call printchar
push bx
mov al, bl
call printchar
call newline
mov si, read_write_success
call print
call newline
ret
请记住,之前的所有“第二部门”在2个月前写的一切后,已被写入在过去2天。我也使用NASM来组装代码。
这里是它在做什么imgur
您正在屏幕上打印一些文本,然后试图从屏幕上读取此文本的前3个字符。对?
使用BIOS功能08h可以达到这个效果,但是您忘记每次都放置光标!
call newline
mov si, read_attempt
call print
call newline ;(*)
这才刚刚输出一些文字离开光标下面它的第一个字符。
要找出需要使用BIOS功能03h的行,然后上行1行。
您只需指定BH
中的显示页面,只要您不使用BH
寄存器即可!
重要提示:不要忘记指定功能编号。
mov bh, 0 ;Select display page 0
mov ah, 03h ;BIOS.GetCursor -> CL, CH, DL, DH
int 10h
dec dh ;Go 1 row up, Column is at 0 because of (*)
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 1st character on stack
无需重新读取光标位置,因为DL
和DH
寄存器仍然稳住了阵脚。只是递增列DL
并设置它通过BIOS:
inc dl ;Go 1 column right
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 2nd character on stack
重复了第三个字符:因为如何
pop ax ;Restore 3rd character
call printchar
pop ax ;Restore 2nd character
call printchar
pop ax ;Restore 1st character
call printchar
:
inc dl ;Go 1 column right
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 3rd character on stack
打印使用堆栈工作字符将以相反顺序显示 。
如果顺序很重要,那么在第三个角色的屏幕上开始阅读并开始工作。
mov bh, 0 ;Select display page 0
mov ah, 03h ;BIOS.GetCursor -> CL, CH, DL, DH
int 10h
MOV DL, 2 ;START AT 3RD CHARACTER
dec dh ;Go 1 row up
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 3rd character on stack
DEC DL ;GO 1 COLUMN LEFT
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 2nd character on stack
DEC DL ;GO 1 COLUMN LEFT
mov ah, 02h ;BIOS.SetCursor
int 10h
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH
int 10h
push ax ;Save 1st character on stack
...
pop ax ;Restore 1st character
call printchar
pop ax ;Restore 2nd character
call printchar
pop ax ;Restore 3rd character
call printchar
BIOS光标位置是从零开始的。因此第三个字符在'DL = 2'。 – Fifoernik
您正在使用推,你的意思是流行,反之亦然图片。 Push会在堆栈中保存一个值,然后pop从堆栈中检索一个值。因此,代码被写入的方式,它会在bl中打印三次。它也会扰乱堆栈上的返回地址。确保你的推动和流行是平衡的。
所以我颠倒了弹出并推送,现在它不打印任何东西 – Psaidiwd
我不认为诠释10h,啊= 08h做你认为它的确如此。我建议你阅读关于int 10h的内容,然后更详细地描述你正在尝试做什么。 – prl
做int 10h和ah = 08h应该“读取光标位置的字符和属性”并将char放入al中,这样我就可以执行一个mov bl,al并将它推入堆栈供以后使用 – Psaidiwd
这是正确的;光标位置处的字符是什么?另外,int 10h的其他要求是什么? – prl