2011-07-21 9 views

答えて

7

function 0Ahを使用すると、バッファされた入力を読み取ることができます。

Byte 0 String length (0-255) 
Byte 1 Bytes read (0-255, filled by DOS on return) 
Bytes 2-..Length+2 (The character string including newline as read by DOS). 

列を読み出してバックユーザにそれをエコー表示小さなCOMファイルの例:

ds:dxの文字列バッファ与えられ、それはバッファレイアウトが長さ255までの文字列を読み取りますそれは入力行を上書きすること
org 0x100 

start: 
    push cs 
    pop ds ; COM file, ds = cs 

    mov ah, 0x0A ; Function 0Ah Buffered input 
    mov dx, string_buf ; ds:dx points to string buffer 
    int 0x21 

    movzx si, byte [string_buf+1] ; get number of chars read 

    mov dx, string_buf + 2 ; start of actual string 

    add si, dx ; si points to string + number of chars read 
    mov byte [si], '$' ; Terminate string 

    mov ah, 0x09 ; Function 09h Print character string 
    int 0x21 ; ds:dx points to string 

    ; Exit 
    mov ax, 0x4c00 
    int 0x21 

string_buf: 
    db 255 ; size of buffer in characters 
    db 0 ; filled by DOS with actual size 
    times 255 db 0 ; actual string 

ノート(と、それはそのプログラムが何をやっている見ていない可能性があります!)

別の方法としては、function 01hを使用して、ループ内の文字を自分で読むことができます。次のようなものがあります(255文字を超える文字が入力された場合は、あとでバッファオーバーフローします)。

org 0x100 

start: 
    push cs 
    pop ax 
    mov ds, ax 
    mov es, ax; make sure ds = es = cs 

    mov di, string ; es:di points to string 
    cld ; clear direction flag (so stosb incremements rather than decrements) 
read_loop: 
    mov ah, 0x01 ; Function 01h Read character from stdin with echo 
    int 0x21 
    cmp al, 0x0D ; character is carriage return? 
    je read_done ; yes? exit the loop 
    stosb ; store the character at es:di and increment di 
    jmp read_loop ; loop again 
read_done: 
    mov al, '$' 
    stosb ; 'Make sure the string is '$' terminated 

    mov dx, string ; ds:dx points to string 
    mov ah, 0x09 ; Function 09h Print character string 
    int 0x21 

    ; Exit 
    mov ax, 0x4c00 
    int 0x21 

string: 
    times 255 db 0 ; reserve room for 255 characters 
+0

だから私は 'string db" $ "'を作ることができますか?それは働くだろうか? – AlbatrosDocsCoder

+0

'$'(ah = 09h関数のターミネータ)だけを含む1バイトの文字列が必要な場合は、読み込んだ文字を格納する場所はありません。 'times 255 db'はdb 0、0、0、0、[snip 250 times 0、]、0と同じです。これは、文字を格納する余地があることを保証します。別のアセンブラを使用している場合は、スペースを予約する構文が異なる場合があります(および/または動的メモリ割り当てを使用できます)。 – user786653

+0

すごくうれしいです。 – AlbatrosDocsCoder

1

文字列は単なる一連の文字なので、ループ内でint 21コードを使用して一度に1文字ずつ文字列を取得できます。文字列を保持するラベルをデータセグメントに作成し、文字を読み取るたびにそのラベルにコピーします(毎回オフセットをインクリメントして文字が順番に格納されるようにします)。特定の文字が読み込まれたときにループを止める(おそらく入力する)。

これをすべて手作業で行うのは面倒です(バックスペースの仕組みについて考えてください)。また、stdio、stdlibなどとリンクしたり、ライブラリ関数を呼び出して多くの作業を行うことができます。

+0

ありがとうございます。しかし、私はそれを作る方法を知っていません。私はそれが 'movああ、1hのようなprocになることを知っている – AlbatrosDocsCoder

+0

私はその投稿を編集することはできません。どうもありがとうございました。しかし、私はそれをすべて作る方法はわかりません。私はラベルにもっと多くの文字を挿入する方法を知らない。だから私は 'string db" $$$ "'を持ち、今は何ですか?私は 'movの文字列、私はできますか? DBに文字を押した?はいの場合は、次に何をするよりも?私は文字の位置を増やすためにホを知りません...あなたはここにサンプルコードを置くことができますか? – AlbatrosDocsCoder

+0

うまくいけば、これはあなたとまだ関係があります。ラベルを使用するのではなく、レジスタ内のメモリの場所を保持することができます。そうすれば、毎回ラベルに書き込むのではなく、レジスタにあるメモリアドレスに書き込むことができます。その後、アドレスレジスタを変更するごとに(各文字ごとにインクリメント)、新しいメモリ位置に書き込みます。 – Quinn