3

アセンブリで作成した関数内でprintfを使用すると、問題が発生します。私が作った関数は次のとおりです。

printnstars:
    movl $0, %edi
    movl 4(%esp), %ebx

starloop:
    cmpl %ebx, %edi
    je exitloop
    incl %edi
    pushl $star
    call printf
    addl $4, %esp
    jmp starloop

exitloop:
    ret

この関数は、%ebxに移動した数値をパラメーターとして受け取り、以下を使用してその数値の「*」を出力します。

star:
    .asciz "*"

この関数は本来の機能を果たしますが、次のようなことをしようとすると問題が発生します。

    pushl (%ecx)
    call printnstars
    pushl (%ecx)
    call printnstars

ここで、(%ecx)は2です。1回だけ呼び出すと、期待どおりに動作し、2つの星が出力されますが、もう一度呼び出すと、無限の星が出力されます。作成したものでそのレジスタを使用しなかったため、%ecxがprintfの内部で混乱したに違いないことは明らかです。printnstarsへの複数の呼び出しを通じて(%ecx)が一定に保たれるようにするにはどうすればよいですか?

また、これは、数値が発生する回数を参照する各行に星が付いたヒストグラムを出力する関数の内部で使用されることに注意してください。私はすべての頻度値を%ecxに基づいているので、(%ecx)を使用しているのはそのためです。

4

1 に答える 1

2

printnstarsへの複数の呼び出しを通じて(%ecx)が一定に保たれるようにするにはどうすればよいですか?

レジスタ値をスタックのローカル変数に保存します。

printf()また、これは可変数のパラメーターを取り、それらがいくつあり、どのタイプであるかを事前に知らないため、スタック上のパラメーターを削除せず、(調整によってesp)スタックからそれらを削除することを覚えておいてください。発信者の責任。

于 2013-02-22T23:12:26.333 に答える