1

私は8086アセンブリに非常に慣れていないため、ずさんなコードとおそらく不要な行を許してください。独学です。このコードは、私が作成している別のプログラムの一部であり、ユーザーが数値を入力する必要があります。これらの特定の行は入力を受け取り、コンピューターが実際に処理できる数値を生成します。たとえば、5、4、および 3 を取り、その数を 543 に「コンパイル」します。

問題は 59 行目で発生します。ここでは、メモリからレジスタ bx に数値をロードし直そうとしています。この場合、40 (543 の例から) のような正しい数値をロードする代わりに、1 をロードするだけです。

59 行目以降の一部のコードは機能しない可能性があります。

私はおそらく正しいレジスタを使用していませんが、繰り返しますが、私は独学であり、オンラインで構文に関する情報を理解しやすいものを見つけるのは難しいです。

org  100h

mov si, 100d

input1:
    mov ah, 1h      ;input char
    int 21h
    push ax
    sub al, 30h     ;convert ascii to integer
    mov dl, al      ;put char into dl to be read
    mov [si], al    ;save char to ram for later
    mov ah, 2h      ;output char
    inc si          ;to save on next location in mem 
    pop ax
    cmp al, 13      ;check if done
    jne input1

    dec si              ;insert terination char 
    dec si              ;decrement to save value of si for multilying by ten
    push si             ;save current si value
    inc si              ;then continue
    mov al, 24h
    mov [si], al

    pop si
    mov cx, 1

    compileNum1:
        mov ax, 0
        mov bx, 0
        mov dx, 0    
    .fixNum:
        mov al, [si]   ; load last num into ax to be multiplied by 10
        mul cx
        mov bp, ax
        mov [si], bp
        dec si
        mov al, 10
        mov bx, cx
        mul bl
        mov cx, ax           
        cmp si, 99d
        jne .fixNum

    mov si, 100d       ;starts number addition

    mov ax, [si]       ;loads first number
    inc si             ;prepares second
    mov bx, [si]       ;loads second

    cmp bx, 24h        ;checks if there was only 1 number
    je .terminate1     ;if there was, goto terminate

    add ax, bx         ;else add them together

    .stloop1:
        inc si         ;prepares for third, fourth etc
        mov bx, [si]   ;loads it

        cmp bx, 24h    ;checks if numbver is 3 digts ot more long (depends on loop)
        je .terminate1 ;terminate if so

        add ax, bx     ;add them together, store in ax

    .terminate1:
        mov [100d], ax





mov ax, 0   ;clear screen
int 10h 


mov ah, 2h  ;print char
int 21h

mov ah, 0   
int 16h
ret

助けてくれてありがとう!

4

1 に答える 1

0

私が通常「キーボードから数値を取得する」ために使用するアルゴリズムは、実際には「キーボードからテキストを取得して数値に変換する」ことであり、次のようになります。

プレループ:

「これまでの結果」レジスタをゼロに設定します。

16 ビットレジスタを 10 に設定して乗数として使用する

ループ:

テキスト文字を取得します。あなたがやっているように、一度に 1 つずつ取得することも、ユーザーが配置した入力バッファーから一度に 1 つずつ読み込むこともできます。

10 進数があることを確認してください。厄介なユーザーはどんなことでも入力します。「+」および/または「-」を受け入れたい場合があります。あなたがやっているように最後ではなく、ここで13(CR)または他の終了文字を監視します(実際には「数値に変換」アルゴリズムをCRに適用したくありません)。「ガベージ入力」については、必要に応じて実行できます。

最も簡単なことは、行儀の良いユーザーを想定することです。私は通常、これまでに取得した数値を返すだけです-たとえゼロであっても。礼儀正しいエラー メッセージを表示して、再試行させるのが最善です。

有効な 10 進数を取得したら'0'、文字から減算します。これは数字の 0 ではなく文字「0」であることに注意してください。必要に応じて 48 または 30h と呼ぶこともできますが、「0」の方が多いと思います。 「何のためにあるのか」が一目瞭然。

次に、「これまでの結果」に 10 を掛けます。

次に、現在の桁から取得した数値を加算します。これは少しトリッキーかもしれません。できませんadd ax, bl。できますがadd ax, bx、 がゼロであることを確認する必要bhがあります! (目的に合わせてレジスタを変更してください)

その CR (または他の終了文字) が見つかるまで繰り返します。それだけです、数字は「これまでの結果」にあります。

お役に立てれば。あなたは正しい道を進んでいますが、必要以上に複雑になっていると思います。ここまで自力で解決してくれてありがとう!

「数字からテキストへ」の部分に関して言えば、先日ここに常連の一人が投稿した本当に甘くて簡単な例を見ました。記憶力が悪い。必要な場合は、おそらく見つけることができます。

于 2013-06-20T05:57:31.040 に答える