-1

私は現在NASMを学んでおり、シフトと加算を通じてユーザー入力変数の乗算を行う簡単なプログラムを作成しています。

私は一連の問題に直面してきました: 私の被乗数は、何らかの理由で、単語が保持できる最大データ値で与えられています。さらに、プログラムがそこまで到達する必要がある場合、私の答えはほとんどの場合間違っています (私のアルゴリズムは正しいと信じていますが!)。

extern printf
extern scanf

section .data
    message: db "Enter your multiplicand: "
    message_L: equ $-message
    message2: db "The number you entered is: %d ", 10, 0
    message2_L: equ $-message2
    message3: db "Enter your multiplier: "
    message3_L: equ $-message3
    message4: db "Your multiplier is: %d ", 10, 0
    message4_L: equ $-message4
    message5: db "The product of this multiplication is: %d ", 10, 0
    mesasge5_L: equ $-message5
    fmt1: db "%d", 0

section .bss
    multiplicand: resw 1
    multiplier: resw 1
    product: resw 1

section .text
    global main
scanInt:
    push ebp
    mov ebp, esp
    sub esp, 2
    lea eax, [ebp-2]
    push eax
    push dword fmt1
    call scanf
    mov ax, word[ebp-2]
    mov esp, ebp
    pop ebp
    ret

main:
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx

    mov eax, 4
    mov ebx, 1
    mov ecx, message
    mov edx, message_L
    int 80h

        call scanInt
        mov word[multiplicand], ax
    mov word[product], ax

    jmp print1
main2:
    mov eax, 4
    mov ebx, 1
    mov ecx, message3
    mov edx, message3_L
    int 80h

    call scanInt
    mov word[multiplier], ax

    jmp print2
main3:
    mov ax, word[multiplicand]
    jmp check
check:
    cmp word[multiplier], 2
    jz printAnswer
    ror [multiplier], 1
    shl word[multiplier], 1
    jc carry
    shr word[multiplier], 1
    shr word[multiplier], 1
    shl word[product], 1
    jmp check

carry:
    add word[product], ax
    shr word[multiplier], 1
    clc
    jmp check

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

printAnswer:
    push ebp
    mov ebp, esp
    push word[product]
    push dword message5
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp endLoop

print1:
    push ebp
    mov ebp, esp
    push dword[multiplicand]
    push dword message2
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp main2

print2:
    push ebp
    mov ebp, esp
    push dword[multiplier]
    push dword message4
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp main3
4

1 に答える 1

1

あなたの主な問題は、word変数の使用にあると思います。スタック上に 2 バイトのバッファーを作成し、scanfそれを読み取るために呼び出しを行うことは、ほぼ確実に問題になります。word32 ビット コードでのプッシュは「合法」ですが、問題が発生する可能性があります。あるインスタンスではprintf、2 つの変数を使用して呼び出し、add esp, 12その後で呼び出します。それらをすべてdwords にして、スタック操作を 4 バイトのチャンクに保ちます。そうすればほとんどの問題は解決すると思います。

マニュアル ページでは、高レベルのバッファー I/O 関数と低レベルの関数を混在させないことを明示的に提案しています ( printfscanffopen()fread()fwrite()などは高レベル関数、open()read()write()... であり、システム コールは低レベル関数です)。これが問題を引き起こしているとは思いませんが、奇妙な結果を引き起こす可能性があります。たとえばprintf、バッファがフラッシュされるまで何も出力しません。改行で終了するか、別の高レベル I/O 関数を使用すると、バッファがフラッシュされます。sys_readたとえば、そうではありません。私はどちらか一方に固執します。

幸運を!

于 2013-06-05T19:54:48.693 に答える