2017-09-23 27 views
1

所以我开始写一个“内核”这样说,我正在尝试读取一个字符串并将其打印回我。问题出现在我执行它时,它只是打印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

+0

我不认为诠释10h,啊= 08h做你认为它的确如此。我建议你阅读关于int 10h的内容,然后更详细地描述你正在尝试做什么。 – prl

+0

做int 10h和ah = 08h应该“读取光标位置的字符和属性”并将char放入al中,这样我就可以执行一个mov bl,al并将它推入堆栈供以后使用 – Psaidiwd

+0

这是正确的;光标位置处的字符是什么?另外,int 10h的其他要求是什么? – prl

回答

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 

重复了第三个字符:因为如何

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 
+1

BIOS光标位置是从零开始的。因此第三个字符在'DL = 2'。 – Fifoernik

2

您正在使用推,你的意思是流行,反之亦然图片。 Push会在堆栈中保存一个值,然后pop从堆栈中检索一个值。因此,代码被写入的方式,它会在bl中打印三次。它也会扰乱堆栈上的返回地址。确保你的推动和流行是平衡的。

+0

所以我颠倒了弹出并推送,现在它不打印任何东西 – Psaidiwd

相关问题