我的读写字符串函数吐出 %%% 而不是我输入的 3 个字符
My read and write string function spits out %%% instead of the 3 characters I put in
所以我已经开始写一个“内核”,可以这么说,我正在尝试读取一个字符串并将其打印回给我。当我执行它时问题就来了,它只打印 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 到 assemble 代码。
这是它正在做的事情的图片imgur
您在使用 push 时表示 pop,反之亦然。 Push 在堆栈上保存一个值,而 pop 从堆栈中检索一个值。所以代码的写法,打印了三次bl中的值。它还会弄乱堆栈上的 return 地址。确保你的推动和弹出是平衡的。
您正在屏幕上打印一些文本,然后试图从屏幕上读取该文本的前 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
重复第三个字符:
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
打印使用:
pop ax ;Restore 3rd character
call printchar
pop ax ;Restore 2nd character
call printchar
pop ax ;Restore 1st character
call printchar
由于堆栈的工作原理,字符将以相反的顺序显示。
如果顺序很重要,请从屏幕上的第 3 个字符开始阅读,然后从头开始阅读。
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
所以我已经开始写一个“内核”,可以这么说,我正在尝试读取一个字符串并将其打印回给我。当我执行它时问题就来了,它只打印 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 到 assemble 代码。
这是它正在做的事情的图片imgur
您在使用 push 时表示 pop,反之亦然。 Push 在堆栈上保存一个值,而 pop 从堆栈中检索一个值。所以代码的写法,打印了三次bl中的值。它还会弄乱堆栈上的 return 地址。确保你的推动和弹出是平衡的。
您正在屏幕上打印一些文本,然后试图从屏幕上读取该文本的前 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
重复第三个字符:
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
打印使用:
pop ax ;Restore 3rd character
call printchar
pop ax ;Restore 2nd character
call printchar
pop ax ;Restore 1st character
call printchar
由于堆栈的工作原理,字符将以相反的顺序显示。
如果顺序很重要,请从屏幕上的第 3 个字符开始阅读,然后从头开始阅读。
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