『ソフトウェアデバッグ分析技術』学習ノート(六)
異或演算は、同じであれば1、異なるであれば0である.非演算、ゼロは1、1はゼロです.機械数と演算の原理が分かったら、プログラム演算における具体的な使い方を見てみましょう.C言語コードは以下の通りである.
このコードは、3つの整数変数a、b、cを定義し、変数aに1を割り当て、変数bに2を割り当て、その後、それぞれ加算、減算、乗算、除去、モード、および、または、異または非演算を行う.逆アセンブリコードを参照:
ここではスタックの上部を高くして、定義されたローカル変数の格納空間を開くために使用します.1つの整数変数が4バイトを占めると、0 x 03バイトは、整数変数a、b、cを格納するための3つの整数変数の空間を開くことができる.
この2つの文はそれぞれC言語コードa=1に対応する.およびb=2.整数変数a,bに値を割り当てるために使用される.
ここで変数aをeaxにとり,eaxと変数bを加算し,最後に結果を変数cに入れる.
ここで変数aをecxにとり,ecxと変数bを減算し,最後に結果を変数cに入れる.
ここで変数aをedxにとり,edxと変数bを乗算し,最後に結果を変数cに入れる.
ここで変数aをeaxにとり,次にシンボルビットを拡張し,変数bを除いて商を変数cに入れる.
ここでは変数aをeaxにとり,次に符号ビットを拡張し,変数bを除いて最後に余数を変数cに入れるが,ここでは上の除算演算のコードとよく似ており,最後に演算結果を格納する場合のみ異なり,除算演算はeaxの値を格納し,モデリング演算はedxの値を格納する.注意深い読者は気づいたかもしれませんが、除算をするときにcdq指令が1本増えました.それは何をしていますか.また、idiv命令は1つの操作数しかありません.それはどのように除算演算を完了しますか.実はdcq命令の役割は、2文字記号を8バイトに拡張することであり、eaxのシンボルビットをedxレジスタに拡張することを指す.すなわち、eaxが8000000未満の場合はedxを00000000、eaxが8000000以上の場合はedxをFFFFFFFFFFFFFFFFとする.idiv命令はシンボル除算であり,除数のない命令に落札され,edx:eaxである.idiv命令にオペランドがある場合、除数はオペランドである.オペランドがなければ、除数はecxです.命令の演算結果:eaxは商であり、edxは残数である.
ここで変数aをecxにとり,ecxと変数bを演算し,最後に結果を変数cに入れる.
ここで変数aをecxにとり,ecxと変数bを演算し,最後に結果を変数cに入れる.
ここで変数aをedxにとり,edxと変数bを異或演算し,最後に結果を変数cに入れる.
ここで変数aをeaxにとり,eaxと変数bを非演算し,最後に結果を変数cに入れる.
#include <stdio.h>
int main()
{
int a, b, c;
a = 1;
b = 2;
c = a + b;
c = a - b;
c = a * b;
c = a / b;
c = a % b;
c = a & b;
c = a | b;
c = a ^ b;
c = ~a;
return 0;
}
このコードは、3つの整数変数a、b、cを定義し、変数aに1を割り当て、変数bに2を割り当て、その後、それぞれ加算、減算、乗算、除去、モード、および、または、異または非演算を行う.逆アセンブリコードを参照:
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 0Ch
ここではスタックの上部を高くして、定義されたローカル変数の格納空間を開くために使用します.1つの整数変数が4バイトを占めると、0 x 03バイトは、整数変数a、b、cを格納するための3つの整数変数の空間を開くことができる.
.text:00401006 mov [ebp+a], 1
.text:0040100D mov [ebp+b], 2
この2つの文はそれぞれC言語コードa=1に対応する.およびb=2.整数変数a,bに値を割り当てるために使用される.
.text:00401014 mov eax, [ebp+a]
.text:00401017 add eax, [ebp+b]
.text:0040101A mov [ebp+c], eax
ここで変数aをeaxにとり,eaxと変数bを加算し,最後に結果を変数cに入れる.
.text:0040101D mov ecx, [ebp+a]
.text:00401020 sub ecx, [ebp+b]
.text:00401023 mov [ebp+c], ecx
ここで変数aをecxにとり,ecxと変数bを減算し,最後に結果を変数cに入れる.
.text:00401026 mov edx, [ebp+a]
.text:00401029 imul edx, [ebp+b]
.text:0040102D mov [ebp+c], edx
ここで変数aをedxにとり,edxと変数bを乗算し,最後に結果を変数cに入れる.
.text:00401030 mov eax, [ebp+a]
.text:00401033 cdq
.text:00401034 idiv [ebp+b]
.text:00401037 mov [ebp+c], eax
ここで変数aをeaxにとり,次にシンボルビットを拡張し,変数bを除いて商を変数cに入れる.
.text:0040103A mov eax, [ebp+a]
.text:0040103D cdq
.text:0040103E idiv [ebp+b]
.text:00401041 mov [ebp+c], edx
ここでは変数aをeaxにとり,次に符号ビットを拡張し,変数bを除いて最後に余数を変数cに入れるが,ここでは上の除算演算のコードとよく似ており,最後に演算結果を格納する場合のみ異なり,除算演算はeaxの値を格納し,モデリング演算はedxの値を格納する.注意深い読者は気づいたかもしれませんが、除算をするときにcdq指令が1本増えました.それは何をしていますか.また、idiv命令は1つの操作数しかありません.それはどのように除算演算を完了しますか.実はdcq命令の役割は、2文字記号を8バイトに拡張することであり、eaxのシンボルビットをedxレジスタに拡張することを指す.すなわち、eaxが8000000未満の場合はedxを00000000、eaxが8000000以上の場合はedxをFFFFFFFFFFFFFFFFとする.idiv命令はシンボル除算であり,除数のない命令に落札され,edx:eaxである.idiv命令にオペランドがある場合、除数はオペランドである.オペランドがなければ、除数はecxです.命令の演算結果:eaxは商であり、edxは残数である.
.text:00401044 mov eax, [ebp+a]
.text:00401047 and eax, [ebp+b]
.text:0040104A mov [ebp+c], eax
ここで変数aをecxにとり,ecxと変数bを演算し,最後に結果を変数cに入れる.
.text:0040104D mov ecx, [ebp+a]
.text:00401050 or ecx, [ebp+b]
.text:00401053 mov [ebp+c], ecx
ここで変数aをecxにとり,ecxと変数bを演算し,最後に結果を変数cに入れる.
.text:00401056 mov edx, [ebp+a]
.text:00401059 xor edx, [ebp+b]
.text:0040105C mov [ebp+c], edx
ここで変数aをedxにとり,edxと変数bを異或演算し,最後に結果を変数cに入れる.
.text:0040105F mov eax, [ebp+a]
.text:00401062 not eax
.text:00401064 mov [ebp+c], eax
ここで変数aをeaxにとり,eaxと変数bを非演算し,最後に結果を変数cに入れる.
text:00401067 xor eax, eax
.text:00401069 mov esp, ebp
.text:0040106B pop ebp
.text:0040106C retn