C++ 反汇编:数据类型与常量( 四 )

<&printf>]| 输出乘法最终结果0041140C | 83C4 08| add esp,0x8|
计算除法是应遵循:
如果除数为8位则被除数为16位,则结果的商存放与al中,余数存放ah中.
如果除数为16位则被除数为32位,则结果的商存放与ax中,余数存放dx中.
如果除数为32位则被除数为64位,则结果的商存放与eax中,余数存放edx中.
cdq指令扩展标志位 edx存储高位:eax存储低位
00411416 | C745 D4 E8030000| mov dword ptr ss:[ebp-0x2C],0x3E8| a = 0x3E8 => 10000041141D | C745 C8 14000000| mov dword ptr ss:[ebp-0x38],0x14| b = 0x14 => 2000411424 | 8B45 D4| mov eax,dword ptr ss:[ebp-0x2C]| eax = ebp-0x2c => 0x3E800411427 | 99| cdq| 把eax的第31bit复制到edx的每个bit上00411428 | F77D C8| idiv dword ptr ss:[ebp-0x38]| 除法 eax = [ebp-0x2C]/[ebp-0x38] => eax/0x140041142B | 8BF4| mov esi,esp|0041142D | 50| push eax| 输出eax里面的值,就是除法结果.0041142E | 68 70584100| push consoleapplication1.415870| 415870:"a/b 结果是: %d\n"00411433 | FF15 14914100| call dword ptr ds:[<&printf>]|00411439 | 83C4 08| add esp,0x8|
上方代码中所展示的都是基于Debug版本的编译方式,可以说该版本没有经过任何优化,所以乘除法是通过计算后得到的结果,下面这段代码是版本代码,你可以清楚地看出代码中并没有任何与计算乘除法有关的指令,这是因为编译器在编译的时候提前将结果计算出来并打成了常量值,这有助于提高程序的运算效率.
002B1000 | 68 381D0000| push 0x1D38| main.c:4002B1005 | 68 00212B00| push consoleapplication1.2B2100| 2B2100:"x*y*z 结果是: %d\n"002B100A | FF15 90202B00| call dword ptr ds:[<&printf>]|002B1010 | 6A 32| push 0x32| main.c:10002B1012 | 68 14212B00| push consoleapplication1.2B2114| 2B2114:"a/b 结果是: %d\n"002B1017 | FF15 90202B00| call dword ptr ds:[<&printf>]|002B101D | 83C4 10| add esp,0x10|002B1020 | 33C0| xor eax,eax| main.c:11002B1022 | C3| ret| main.c:12
递增/递减运算符: 递增递减运算符也是C语言中最常用的运算元素.
#include int main(int argc, char* argv[]){int x = 10;printf("x+1 = > %d\n", x + 1);printf("x+=2 => %d\n", x -= 2);printf("++x => %d\n", ++x);printf("x++ => %d\n", x++);return 0;}
如下就是递增递减的代码片段,可以看出这几种的差别并不大,这里直接省略了.
004113DE | C745 F8 0A000000| mov dword ptr ss:[ebp-0x8],0xA| 10004113E5 | 8B45 F8| mov eax,dword ptr ss:[ebp-0x8]| eax = 10004113E8 | 83C0 01| add eax,0x1| eax = eax+1004113EB | 8BF4| mov esi,esp|004113ED | 50| push eax|004113EE | 68 58584100| push consoleapplication1.415858| 415858:"x+1 = > %d\n"004113F3 | FF15 14914100| call dword ptr ds:[<&printf>]|00411403 | 8B45 F8| mov eax,dword ptr ss:[ebp-0x8]| eax = 1000411406 | 83E8 02| sub eax,0x2| eax = eax-200411409 | 8945 F8| mov dword ptr ss:[ebp-0x8],eax|0041140C | 8BF4| mov esi,esp|0041140E | 8B4D F8| mov ecx,dword ptr ss:[ebp-0x8]|00411411 | 51| push ecx|00411412 | 68 68584100| push consoleapplication1.415868|00411417 | FF15 14914100| call dword ptr ds:[<&printf>]|
复合运算符: 复合运算就是运算符中嵌套另一个运算表达式,该表达式就是符合运算表达式.
#include int main(int argc, char* argv[]){int x = 10, y = 34,z = 22;int a = (x + z + y);int b = a * 3;printf("当前b= %d\n", b);return 0;}
Debug反汇编代码如下,如果是那么这些变量也会被计算出结果并赋予一个常量,所以这里只能使用Debug版查看.
004113DE | C745 F8 0A000000| mov dword ptr ss:[ebp-0x8],0xA| 10004113E5 | C745 EC 22000000| mov dword ptr ss:[ebp-0x14],0x22| 34004113EC | C745 E0 16000000| mov dword ptr ss:[ebp-0x20],0x16| 33004113F3 | 8B45 F8| mov eax,dword ptr ss:[ebp-0x8]| eax = 10004113F6 | 0345 E0| add eax,dword ptr ss:[ebp-0x20]| eax = eax + 33004113F9 | 0345 EC| add eax,dword ptr ss:[ebp-0x14]| eax = eax + 34004113FC | 8945 D4| mov dword ptr ss:[ebp-0x2C],eax| mov [ebp-0x2C], 10+33+34004113FF | 6B45 D4 03| imul eax,dword ptr ss:[ebp-0x2C],0x3 | imul eax,77,03 => 77乘3结果存入eax00411403 | 8945 C8| mov dword ptr ss:[ebp-0x38],eax| 赋值到临时变量00411406 | 8BF4| mov esi,esp| main.c:9, esi:__enc$textbss$end+10900411408 | 8B45 C8| mov eax,dword ptr ss:[ebp-0x38]|0041140B | 50| push eax|0041140C | 68 58584100| push consoleapplication1.415858| 415858:"当前b= %d\n"00411411 | FF15 14914100| call dword ptr ds:[