2017-09-23 28 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

相關問題