我的读写字符串函数吐出%%%而不是我输入的3个字符

时间:2017-09-23 16:13:24

标签: assembly kernel nasm x86-16

所以我开始写一个"内核"所以说,我试图读取一个字符串并将其打印回给我。当我执行它并且它只打印3个相同的char而不是我在线上写的那个时,就会出现问题。

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个月前写的一样,之后的所有内容都是在过去两天写的。我也使用NASM来汇编代码。

以下是它正在做什么imgur

的图片

2 个答案:

答案 0 :(得分:2)

你使用push表示pop,反之亦然。 Push会在堆栈上保存一个值,pop会从堆栈中检索一个值。因此编写代码的方式,它会在bl中打印三次值。它还会混淆堆栈上的返回地址。确保您的推动和弹出均衡。

答案 1 :(得分:2)

您在屏幕上打印了一些文字,然后尝试从屏幕上读取此文字的前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

无需重新读取光标位置,因为DLDH寄存器仍然保持位置。只需增加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

重复第3个字符:

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