banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

「ゼロから始めるIDAリバースエンジニアリング」学習ノート-6(整数と論理演算)」

以下のテキストを「日本語」に翻訳してください:
image

6.1 整数演算命令#

ADD#

ADD A,B命令は B の値を A に加え、結果を A に保存します。A はレジスタまたはメモリの値であることができます。B はレジスタ、定数、またはメモリの値であることができます。同じ命令内で、A と B は同時にメモリの値であってはなりません。

上記の図では、多くの ADD 命令の例があります。これらの例では、最初のオペランドはレジスタであり、2 番目のオペランドは定数です。したがって、プログラム実行時には、定数とレジスタの値を加算した結果が再びそのレジスタに保存されます。

上記の図では、ECX = 10000の場合、定数 4 を加えると結果は 10004 になり、結果がECXに再保存されます。

上記の図では、ADD 命令はECX+30で指定されたアドレスに格納されている値に定数0xffffffffを加えます。プログラムがこのアドレスに書き込み権限を持っている場合、計算結果もこのアドレスに保存されます。ECX = 0x10000と仮定すると、30 を加えると0x10030になります。このアドレスに保存されている数が 1 である場合、定数0xffffffffを加えると - 1 になり、結果は 0 になり、0x10030のアドレスに保存されます。

上記の図では、2 つのレジスタの値を加算し、結果を eax に保存しています。ADD 命令は 16 ビットおよび 8 ビットレジスタにも適用できます。

例:

ADD AL,8
ADD AX,8
ADD BX,AX
ADD byte ptr ds: [EAX],7 # EAXが指すバイトに7を加え、同じアドレスに保存します。

ADD 命令のオペランドでは、A が定数でない限り、または A と B がメモリの値である場合を除き、他のレジスタやメモリの組み合わせはすべて許可されます。

SUB#

SUB A,B命令はADD命令と同じですが、2 つのオペランドを引き算し、最終結果を A に保存します。SUB で許可されるオペランドの組み合わせは ADD と同じです。

上記の図では、SUB の例がいくつかあります。

INC & DEC#

INC AおよびDEC A命令は、レジスタまたはメモリの値に ±1 を加えます。これは加算および減算の特殊なケースです。通常、これらの命令はカウンタに対して ±1 を行うために使用されます。

IMUL#

IMUL は符号付き整数乗算命令であり、2 つの使用方法があります。
IMUL A,BおよびIMUL A,B,C

  • 最初の方法では、A と B を掛け合わせ、結果を A に返します。
  • 2 番目の方法では、B と C を掛け合わせ、結果を A に返します。

これらの 2 つの方法では、A はレジスタである必要があり、B はレジスタまたはメモリの値(最初の方法では定数でも可能)、C は定数である必要があります。

例:

Imul eax, [ecx] 
Imul esi, edi, 25

上記の図では、1 つの使用方法のみが示されており、2 つのオペランドを掛け合わせ、結果を最初のオペランドに保存します。

IDIV#

IDIV A命令では、除数のみが指定されます。被除数は指定されていませんが、保存先は固定されています。

Dividend (D) ➗ divider (d) = quotient (q)
Dividend (D) は被除数、divider (d) は除数、quotient (q) は除算の結果であり、商です。

32 ビット演算では、EDX と EAX は 64 ビットの数を構成し、EDX は上位ビット、EAX は下位ビットになります。この 64 ビットの数を A で除算すると、商が EAX に返され、余りが EDX に返されます。

上記の図では、EAX=5、EDX=0、ECX=2 の場合、5➗2 の結果は 2 で、EAX に保存され、余り 1 が EDX に保存されます。

A がメモリの値である場合も同様で、EDXを A で除算し、商が EAX に返され、余りが EDX に返されます。

6.2 論理演算命令#

まず、AND(ビットごとの論理積)、OR(ビットごとの論理和)、XOR(排他的論理和)演算です。

AND A,B は A と B のビットごとの論理積を計算し、最終結果を A に保存します。OR と XOR 演算も同様です。

A と B はレジスタまたはメモリの値であることができますが、同じ命令内で A と B が両方ともメモリの値であることはできません。

XOR#

最も一般的な例は、同じレジスタに対して XOR(排他的論理和)演算を行い、その値をゼロにすることです。たとえば、XOR EAX,EAXまたは他のレジスタをゼロにします。XOR(排他的論理和)演算の真理値表は上記の図に示されています。同じ数に対して XOR 演算を行うと、結果は 0 になります。操作は 2 進数モードで行われます。

16 進数でも XOR 演算を行うことができます。Python では、XOR は「^」記号で表されます。2 つの同じ値を XOR すると、最終結果は 0 になります。

AND#

and eax,0xf

0xf は 2 進数で 1111 を表します。

0xf の最後の 4 ビットは 1 なので、eax の最後の 4 ビットは変わらず、他のビットはすべて 0 になります。この方法により、eax の最後の 4 ビットが残り、他のビットがクリアされます。

and 演算は Python では「&」記号で表されます。上記の図の結果は 0b111 であり、最下位の 4 ビットです。

OR#

OR 演算は Python では「|」記号で表されます。

NOT#

NOT Aは A のすべてのビットを反転させ、A に保存します。Python ではビットごとの反転は「~」記号で行われます。0101 の場合、結果は各ビットを反転します。すべての 0 は 1 に反転し、すべての 1 は 0 に反転します。

NEG#

NEG Aは A を - A に変換します。NEG 演算はビットごとの反転とは異なり、1 を引いた結果になります。

Python では、NEG を使用して反転後に 1 を加えることができます。

SHL#

SHL A,B

SHR A,B では、A はレジスタまたはメモリの値であり、B は定数または 8 ビットレジスタです。これらの命令はオペランドをビット単位で左または右にシフトし、欠けたビットは 0 で埋めます。たとえば、-1 の場合。

SHL 2 を実行すると、以下の図のようになります。

これらのビットを左にシフトすると、左端の 2 つのビットが削除され、右端の 2 つのビットが 0 で埋められます。

SHR の場合も同様で、これらのビットを右にシフトし、右端のビットが削除され、左端の空きスペースが 0 で埋められます。

ROL および ROR も同様の命令であり、各ビットを一定の位置に移動しますが、一方の端が他方の端に戻ると、内容は変更されません。

この章では、アセンブリ言語の整数演算および論理演算命令について説明しました。基礎を固めるためのものです。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。