2

私はx86アセンブリ言語を初めて使用します。私はpcasmという本を読んでいて、誰かがこのコード例をよりよく理解するのを手伝ってくれるかどうか疑問に思っていました(これは本の部分的なコードです):

32    mov    ebx, input2
33    mov    ecx, $ + 7
34    jmp    short get_int
35
36    mov    eax, [input1]


64    get_int:
65        call   read_int
66        mov    [ebx], eax
67        jmp    ecx

さて、私が理解している$のは、現在の住所を示しているということですが、

  1. なぜ+ 7ですか?
  2. どうすれば計算できますか?
  3. jmp near get_int(4バイト)とjmp near word get_int(2バイト)を使用すると、番号はどうなりますか?2番目の構文は正しいですか、それとも正しいはずjmp word get_intですか?

ありがとう

4

2 に答える 2

2

ええ、カーター博士は「電話」が何をするのか、そしてなぜ私たちがこの回り道をする代わりに「電話」を使うのかについて取り組んでいると思います。

コマンドラインに「-lmyfile.lst」を追加すると、Nasmによってリストファイルが作成されます。

即時の「jmp」の構文は、「jmpshort」と「jmpnear」になります。(「jmpfar」もありますが、それは別のことをします-32ビットコードではあまり役に立ちません)。Nasmの動作は、この点で何年にもわたって変更されています。古いNasmは、「jmp」とだけ言った場合、デフォルトで「jmp near」を提供していました。新しいNasmは、適切な場合は「jmpshort」を使用します。新しいNasmで実際に「nearjmp」を取得するには、「jmp strict near」を使用する必要がある場合があります(または、コマンドラインで「-O0」(大文字の「o」、ゼロ)を使用して最適化をオフにします)。これは、既存のコードを壊すようなものです。オフセット「+7」をハードコーディングすると、「保守不可能な」コードになります。カーター博士は、このようにコーディングするように促しているのではなく、主張して​​いると確信しています。

このコードと「call/ret」の間の「中間」として、サブルーチンを戻したい場所にラベルを付けて、それをecxに入れてみてください。このサブルーチンを複数の場所から「呼び出さない」場合は、「ret_addr1:」、「ret_addr2:」などを実行する必要があります。もちろん、サブルーチン内のecxを変更する必要はありません。「call/ret」を使用すると、スタックを台無しにする必要はありません。通常、より良いトレードオフです。

最高、フランク

于 2012-07-23T06:13:31.127 に答える
2
  1. + 7おそらく、ソース行33と34を合わせて生成された7バイトのマシンコードがあるため、サンプルコードはを使用します。

  2. アセンブラの出力リスト(アセンブラでオンにする必要がある場合があります)を確認し、バイト数を数えることで、必要なオフセットを計算できます。

  3. 異なる数のマシンコードバイトにアセンブルする命令を使用する場合、必要なオフセットは異なります。必要なものを確認するには、環境で試してみる必要があります。

于 2012-07-23T01:07:31.567 に答える