0

NASM マクロを作成します。divide は、任意のアドレッシング モードで符号なし整数を指定する 2 つの引数を持ちます。マクロは、最初の引数の上限を計算し、2 番目の引数で割って、結果をレジスタ edx に配置します。2 番目の引数が 0 (実行時にテストされる) の場合、結果は 0 になり、「ゼロで割る」というメッセージが stdout に出力されます。

これは私が書いたコードです。ラベルなしでこのコードを書く方法は? (位置はコードに依存しません)

%macro divide 2

section .rodata
        LC1: DB "divide by zero ", 10, 0

section .text

  mov eax, %1
  mov ebx, %2
  cmp ebx, 0 ; divide by zero
  jne rest1
  push LC1
  call printf
  add esp,4
  mov edx, 0
  jmp end1

rest1:
  mov edx, 0
  div ebx
  add eax, edx
  mov edx , eax ; the result should be in edx

end1:
 %endmacro
4

1 に答える 1

0

「ラベルなし」と「位置に依存しないコード」にはかなりの違いがあります。どちらか一方は持てますが、もう一方は持てません。両方を持つこともできますし、どちらも持たないこともできます。

上記のコードをラベルなしで作成するのは簡単ではありません。そして、あなたがそれを望む正当な理由がわかりません。あなたが何をしているのか、このタスクの背後にあるより大きな目標を説明できますか?

また、位置に依存しないマクロを作成することもまれです。通常、サブルーチン全体のようなものは位置独立になります。繰り返しますが、なぜそれが必要だと思いますか?

それにもかかわらず、上記のコードのすべてのジャンプおよび呼び出し命令はeip相対です (ドキュメントの jmp/jcc および呼び出し命令の詳細を参照してください)。

そのためjne rest1jmp end1マクロを位置依存にしないでください。これらのジャンプeipは、コードがどこにあるかに関係なく、常に一定量だけ進みます。

OTOH、同じ理由でcall printf(そしておそらくpush LC1) do(es) はマクロを位置依存にします。これを回避するには、 と のアドレスを追加の引数 (明示的 (他の 2 つの引数と同様) または暗黙的 (たとえば、事前定義された場所、レジスタ、またはスタックの場所)) としてマクロに渡しprintfますLC1

于 2012-06-25T11:08:04.500 に答える