組み立て時に簡単な算術プログラムを実装するのに問題がある

私はアセンブリで次のプログラムを実装しようとしています:

int number;
printf("\n%s","Enter an integer: ");
scanf("%d",&number);
number=7-number*3;
printf("\n%s%d\n\n","The integer is: ",number);

これまでのところ、私の試みはこれです:

    .386
    .model flat, c
    .stack 100h
printf PROTO arg1:Ptr Byte, printlist:VARARG
scanf PROTO arg2:Ptr Byte, printlist:VARARG
    .data
in1fmt byte "%d",0
msg1fmt byte 0Ah,"%s",0
msg1 byte "Enter an integer: ",0
msg2fmt byte 0Ah,"%s%d",0Ah,0Ah,0
msg2 byte "The integer is: ",0
number sdword ?
    .code
main proc
    INVOKE printf, ADDR msg1fmt, ADDR msg1
    INVOKE scanf, ADDR in1fmt, ADDR number
    mov eax, number
    mov ebx, 3
    imul ebx
    mov number, eax
    mov eax, 7
    sub eax, number
    INVOKE printf, ADDR msg2fmt, ADDR msg2, eax
    ret
main endp
    end

最初の問題は、eaxが数に格納されていないということです。 eaxを数値に変換した後にnumberの値を出力すると、30の入力に対して21という値が出力されます.eaxは90ですが、eaxを番号番号に移動した後は21になります。

私は単純なものを見逃していると確信していますが、どこが間違っているのか分かりません。

0
もう少し情報を提供できますか?これは完全なコードのようには見えません。
追加された 著者 Jesus Ramos,
それは通常ですが、アセンブリは難しいことです:P
追加された 著者 Jesus Ramos,
デバッガでこのプログラムを実行し、このサブルーチンの各命令の後でレジスタと変数を調べる方法はありますか?それはあなたが物事を乱している場所を教えてくれるでしょう。
追加された 著者 Alexey Frunze,
@JesusRamos私はそれができるだけコードを減らすためにこのサイトで良いと思ったので、私はそれを最小限に抑えました。私は今質問に自分のプログラム全体を追加しました。
追加された 著者 Sonny Ordell,
@Alex私はそれがこのような単純なことのために必要であるとは思わなかったでしょう。確かにこの小さなすべての論理エラーが明らかになるはずのプログラムでは?
追加された 著者 Sonny Ordell,

1 答え

enterMsg db 'Enter an integer: ',0
resultMsg db 'The integer is: %d\r\n',0    ; yep, I refactored this one

stringPattern db '%s',0

; ...


proc main
    push ebp
    mov ebp,esp
    sub esp,4

    lea eax,[ds:enterMsg]
    push eax
    lea eax,[ds:stringPattern]
    push eax
    call printf    ; printf("%s", enterMsg);//btw, why?
    add esp,8


    lea eax,[ebp - 4]
    push eax
    lea eax,[ds:intPattern]
    push eax
    call scanf     ; scanf("%d", &number);
    add esp,8

    mov eax,[dword ptr ss:ebp - 4]
    push eax
    call calculate    ; number = calculate(number);
    add esp,4
    mov [dword ptr ss:ebp - 4],eax

    lea eax,[ebp - 4]
    push eax
    lea eax,[ds:resultMsg]
    push eax
    call printf    ; printf(resultMsg, number);
    add esp,8

    mov esp,ebp
    pop ebp
    ret
endp main


; number=7-number*3;
proc calculate
    push ebp
    mov ebp,esp
    push ebx

    ; not considering integer overflow for now
    mov eax,[dword ptr ss:ebp + 8]
    mov ebx,3
    imul ebx
    neg eax
    add eax,7

    pop ebx
    mov esp,ebp
    pop ebp
    ret
endp calculate

CプログラムはASMに変換するのが簡単です。 cdecl 呼び出し規約では、サブルーチンの引数を右から左にプッシュし、サブルーチンを呼び出して eax (存在する場合)、またはST0をfloat )。その後、スタックをクリーンアップして、それだけです。

私が思う問題は、ポインタの代わりにスタックの結果の値をプッシュすることです。確かに。私はしばらくの間ASMでC rtlを使用していません

0
追加された