1

複数の文字 (文字列または整数) を出力できるプログラムを作成しようとしています。私が抱えている問題は、コードが文字の 1 つだけを出力し、改行して無限ループにとどまることです。これが私のコードです:

SECTION .data
len EQU 32
SECTION .bss
num resb len
output resb len

SECTION .text
GLOBAL _start
_start:
Read:
    mov eax, 3
    mov ebx, 1
    mov ecx, num
    mov edx, len
    int 80h

Point:
    mov ecx, num

Print:
    mov al, [ecx]
    inc ecx
    mov [output], al

    mov eax, 4
    mov ebx, 1
    mov ecx, output
    mov edx, len
    int 80h

    cmp al, 0
    jz Exit

Clear:
    mov eax, 0
    mov [output], eax
    jmp Print  

Exit:
    mov eax, 1
    mov ebx, 0
    int 80h 

誰かが私が間違っていることを指摘できますか?

ありがとう、

ライリー

4

2 に答える 2

2

初めてPrintセクションに入るときecxは、文字列の先頭を指しており、それを使用して1文字を出力文字列の先頭にコピーします。しかし、さらにいくつかの命令を実行すると、出力文字列へのポインタで上書きecxし、復元することはありません。したがって、文字列の残りの部分をコピーして印刷することはできません。

write()また、文字列全体を印刷するためにループすることを目的として、単一の文字列で呼び出すのはなぜですか?num単一の文字をコピーして渡すのではなく、直接渡すのはなぜoutputですか?

于 2012-10-25T12:01:17.337 に答える
1

最後の質問ではmessage、ゼロで終わる文字列として示したので、cmp al, 0文字列の終わりを示します。sys_read はゼロで終わる文字列を作成しません! (必要に応じてそこにゼロを詰め込むことができます。たとえば、sys_open のファイル名として) sys_read は最大 edx 文字を読み取ります。stdin の sys_read は、"enter" キーが押されたときだけ返されます。入力された edx 文字よりも少ない場合、文字列は改行文字 (10 進数または 0xA または 0Ah 16 進数) で終了します - それを探すことができます...バッファに入ると、「余分な」はOSのバッファに残ります(後で問題を引き起こす可能性があります!)。この場合、文字列は改行で終了していないため、検索は失敗します。sys_read は、実際に読み取った文字数 (改行を含む edx まで) を eax で返します。あなたがしない場合

実験として、edx でいくつかの小さな数値 (4 など) を使用して sys_read を実行し、プログラムを終了します。「abcdls」(Enter) と入力し、「ls」が実行されるのを確認します。ジョーカーが「abcdrm -rf .」と入力した場合...まあ、しないでください!!!

最も安全なのは、OS の入力バッファをフラッシュすることです。

    mov ecx, num
    mov edx, len
    mov ebx, 1
    mov eax, 3
    int 80h
    cmp byte [ecx + eax - 1], 10 ; got linefeed?
    push eax ; save read length  - doesn't alter flags
    je good
flush:
    mov ecx, dummy_buf
    mov edx, 1
    mov ebx, 1
    mov eax, 3
    int 80h
    cmp byte [ecx], 10
    jne flush
good:
    pop eax ; restore length from first sys_read

.bss (または .data)で定義する代わりにdummy_buf、スタックに置くことができます - ここではシンプルにしようとしています。これは不完全です。文字列が改行で終了しているかどうかはわかりません。また、エラーをチェックしていません (stdin から読み取る可能性は低い)。「作業を行う」よりも、エラーや「馬鹿なユーザー」の入力を処理するコードをはるかに多く書いていることがわかります。避けられない!(これは低水準言語です。すべてのことを CPU に伝える必要があります!)

sys_write は、ゼロで終わる文字列についても知りません! ガベージの量に関係なく、edx文字を出力します。実際に印刷したい文字数を把握し、それを edx に入れたいとします (そのため、上記の元の長さを保存/復元しました)。

「整数」に言及numし、変数名として使用します。これらの関数はどちらも、ASCII コードを除いて「数字」を認識しません。文字を読み書きしています。1 桁の数字と文字の変換は簡単です。「0」 (10 進数の 48 または 30h) を加算または減算します。複数の数字はより複雑です。必要な場合は、例を探してください。

ベスト、フランク

于 2012-10-25T20:06:48.680 に答える