2017-09-23 4 views
1

"カーネル"を書くようになったので、文字列を読み込んでそれを元に戻そうとしています。私。問題は私がそれを実行すると、私は行の上に書いたものではなく、同じcharの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ヶ月前のように書かれた、すべての後、過去2日間に書かれたことを覚えておいてください。私はまた、NASMを使ってコードをアセンブルしています。ここで

は、それはあなたがポップ意味プッシュおよびその逆を使用しているimgur

+0

int 10h、ah = 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 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文字目のため

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文字目の画面で読み始め、最初に向かって作業してください。

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カーソルの位置はゼロベースです。したがって、3文字目は 'DL = 2 'にあります。 – Fifoernik

2

をやっているものの写真です。 pushはスタックに値を保存し、popはスタックから値を取得します。だから、コードが書かれているように、それはblの値を3回印刷します。それはまた、スタック上のリターンアドレスを混乱させる。プッシュとポップがバランスが取れていることを確認してください。

+0

だから私はポップをプッシュしてプッシュし、今は何もプリントしません。 – Psaidiwd

関連する問題