4

私が言おうとしている文は、StackOverflow で非常に急速に不人気になるためのおそらく最良の方法であることを知っています。とにかく言います:なぜこれは(完全に)うまくいかないのですか?

lea/leal 命令が何をするのかを理解しようとしていました。私が理解している方法では、lea/leal は最初のオペランドのメモリ アドレスを見つけ、このアドレスを 2 番目のオペランド (レジスタなどである可能性があります) に書き込みます。

この部分は機能しているようです。以下のプログラムを実行すると、次のように表示されます。

The memory address of var is 134518204.

ただ、この直後に「メモリアクセスエラー」みたいなのが出てきます。pushl (%eax)は明らかに機能しません。なぜだめですか?

.data
    var:    .long 42
    str1:   .string "The memory address of var is %d.\n"
    str2:   .string "At this memory address we find var's value: %d.\n"

.text
.global main
main: 
    leal var, %eax          # Copy the address of var into %eax
    pushl %eax
    pushl $str1
    call printf             # Print str1
    pushl (%eax)
    pushl $str2
    call printf             # Print str2

    # Some stack cleaning should be here :)

    movl $1, %eax
    int $0x80

lea/leal の機能が正しかったかどうかさえわかりません。助けていただければ幸いです。;)

4

2 に答える 2

2

私が理解している方法では、lea/leal は最初のオペランドのメモリ アドレスを見つけ、このアドレスを 2 番目のオペランド (レジスタなどである可能性があります) に書き込みます。

十分に正確に聞こえます。アドレス演算を実行するために使用されます。これはアドレスをロードするだけの簡単なものですが、それを使用して特定の定数による乗算を実行することもできます。


pushl (%eax)明らかに機能しません。なぜだめですか?

あなたのpush命令は、あなたが考えているアドレスを参照していません:printf書き込まれた文字数を返し、その値は%eaxレジスタに返されるため%eax、のアドレスは含まれなくなりましたvar

于 2013-11-02T15:52:49.237 に答える
2

leaは通常、計算に (ab) 使用されます。レジスタ内のグローバルのアドレスだけが必要なmovl $var, %eax場合は、lea.

また、明確にするために、の宛先オペランドはレジスタでlea なければなりません。

于 2013-11-02T16:15:04.330 に答える