3

次のプログラムで何が問題なのかを把握するために 3 時間以上試行錯誤してきました。私がやろうとしているのは、x を y で除算し、除算とモジュロの結果を出力することだけです。また、 % が内部にあるモジュロの printf は、すべてを台無しにします。誰もそれを修正する方法を知っていますか? 私はアセンブリIA32に取り組んでいます。ユーザーから既に x と y を取得しているとします。

.section    .rodata
format1:    .string "Div : %d / %d = %d\n"
format2:    .string "Mod : %d % %d = %d\n"

    .text
.globl  main    
    .type   main, @function 

# operation divide
movl    x,  %eax
cltd
idivl   y
pushl   %eax
pushl   y
pushl   x
pushl   $format1
call    printf

# operation modulo
pushl   %edx
pushl   y
pushl   x
pushl   $format2
call    printf

モジュロを %edx レジスタに保持する必要があることはわかっていますが、なぜ機能しないのですか? どうもありがとう!D:

編集: OK、%edx を %ebx に保存したところ、モジュロが正常に動作するようになりました。(%edx にあるものを印刷すると、正しいモジュロが得られます) しかし、画面への印刷はまだ私が望むものではありません。これは、x=2、y=4 の出力です。

Divide : 2 / 4 = 0
Modulo : 2 %d = 4

そして、私はそれを次のようにしたい:

Divide : 2 / 4 = 0.50
Modulo : 2 % 4 = 2
4

2 に答える 2

2

EAX、ECX、および EDX は、呼び出し側で保存されたレジスタです。つまり、呼び出す前にそれらを保存する必要printfあります。これらのレジスタは、復元せずに自由に変更できます。

一方、EBX、ESI、および EDI は呼び出し先に保存されます。つまり、すべての関数は呼び出し前に元の内容に復元する必要があります。

于 2012-11-24T17:45:17.260 に答える
2

System V ABI for Intel386によれば、関数はスクラッチ レジスタとして使用でき%ecx%edx呼び出し先は呼び出し元の値を保持する必要はありません。これは、printfの値を上書きすることが許可されていることを意味%edxし、リマイナーの値を破壊します。%edxの値を%esiまたはに転送することで保存できます%edi。仕様に従って、それらの値は呼び出し先によって保持される必要があります (呼び出し元に「属している」)。

これは言った、あなたはにエラーがありますformat2。次のように変更する必要があります。

format2:    .string "Mod : %d %% %d = %d\n"

リテラルは、フォーマット文字列の%ように記述する必要があり%%ます。そうしないと、 によってフォーマット指定子として解釈されprintfます。

于 2012-11-24T17:46:03.583 に答える