异或运算,相同则1,不同则0;非运算,零则一,一则零。
明白了机器数和运算的原理以后来看看它们在程序运算中的具体使用方法。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; }
这段代码定义了三个整型变量a、b、c,给变量a赋值1,给变量b赋值2,然后分别进行加、减、乘、除、模、与、或、异或还有非运算。看反汇编代码:
.text:00401000 push ebp .text:00401001 mov ebp, esp .text:00401003 sub esp, 0Ch
这里抬高栈顶,用来为定义的局部变量开辟储存空间。一个整型变量占4字节,那么0x0C字节则可开辟出三个整型变量的空间,用来储存整型变量a、b、c。
.text:00401006 mov [ebp+a], 1 .text:0040100D mov [ebp+b], 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指令,它是干什么的?还有,idiv指令只有一个操作数它是怎么完成除法运算的。
其实dcq指令的作用是将双字符号扩展至8字节,指的是扩展eax的符号位至edx寄存器中,也就是说,当eax小于80000000时使edx为00000000,当eax大于等于80000000时使edx为FFFFFFFF。
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