【代码真相】之 汇编

寄存器

1. 8个32位寄存器
eax     ebx     ecx     edx
esp     ebp     edi     esi

eax-edx这四个是通用寄存器  ax-dx 访问低十六位,其中ah是高八位 al低八位
esp-esi这四个主要是寻址时用来存放偏移或指针,所以,也就称为指针寄存器或变址寄存器了

ESP(堆栈指针寄存器): 
     指向栈顶
EBP(基址指针寄存器): 
     与堆栈段寄存器SS(堆栈段)联用来确定堆栈中的某一存储单元的地址
     ESP用来指示段顶的偏移地址,而EBP可作为堆栈区中的一个基地址以便访问堆栈中的信息。
     EBP始终指向的是当前函数所在栈区的栈基址。ebp操作上层函数传来的变量时,是通过ebp加上一个数值取参数,当操作自己函数内部定义的变量的时候,是通过EBP减去一个数值来取得。
ESI(源变址寄存器)和EDI(目的变址寄存器)
     一般与数据段寄存器DS联用,用来确定数据段中某一存储单元的地址。
     这两个变址寄存器有自动增量和自动减量的功能,可以很方便地用于变址。

2. EIP(指令指针寄存器): 
     指向的就是下一条将要执行的指令的指针!

3. flags(标志寄存器): 
     存放条件标志码、控制标志和系统标志的寄存器! 
     ZF(零标志) 当计算结果是零时该标志被设置(compare实际上是只设置标志不保存结构的减法) 
     SF(符号标志) 结果为负就设置 
     CF(carry标志) Carry标志中存放计算后最右的位。 
     OF(溢出标志) 标明一个溢出了的计算。如,结构和目标不匹配。

4. 段寄存器:
     cs代码段,ds数据段,ss堆栈段,es附加段
     在Win32编程中段的概念已经不重要了

常用命令

cmp eax,ecx     比较eax和ecx,置标志位!eax-ecx = 0 置zf为1,否则zf为0
jge XXXXXXXX    条件跳转命令 “如果大于等于就跳转”(jge)和“符号标志=溢出标志”一样

xor eax,eax     eax与自己异或,是清零的操作!
lea eax,str     并不传送数据,只传送该数据的地址,将str字符串的地址传到eax
push dword ptr ds:[*****]      在ds(数据段)把[*****]开始的一个双字长数值取出来
     szTextFmt   BYTE '%d',0 
     mov al,byte ptr ds:szTextFmt      就把 % 取出来 而不包括 d

指令的长度
所谓指令的长度,就是描述一条指令所需要的字节数,用一个字节能描述的指令我们叫1字节指令,同理,用两个字节描述的叫2字节指令,用三个字节描述的指令就叫3字节指令。


常用代码结构

1. For循环

for ( int  i = 0 ; i < 100 ; i ++ )
 {
  
// 循环体
 }

 
// Next Line

汇编中的结构是这样的

for( int  i= 0 ;  i<100; i++)
0040179F     mov          dword ptr [ebp- 8 ], 0          // int  i= 0
004017A6     jmp          main+31h ( 004017b1 )
004017A8     mov          eax,dword ptr [ebp- 8 ]     // i++
004017AB     add          eax, 1
004017AE     mov          dword ptr [ebp- 8 ],eax
004017B1     cmp          dword ptr [ebp- 8 ],64h    //和100比较
004017B5     jge          main+42h ( 004017c2 )      //大于等于跳转 i>= 100
29 :       {
.循环体
31 :       }
004017C0     jmp          main+28h ( 004017a8 )
32 :
004017C2    Next Line


2. Whille循环

int j = 0;
while (j<100) {
  //循环体 
}
// Next Line

27 :        int  j =  0 ;
00401798     mov          dword ptr [ebp- 4 ], 0
28 :       while (j< 100 ) {
0040179F     cmp          dword ptr [ebp- 4 ],64h
004017A3     jge          main+30h ( 004017b0 )
29 :         //循环体  
30 :           j++ ;
004017A5     mov          eax,dword ptr [ebp- 4 ]
004017A8     add          eax, 1
004017AB     mov          dword ptr [ebp- 4 ],eax
31 :       }
004017AE     jmp          main+1Fh ( 0040179f )
32 :
33 :        int  szNum[ 5 ] = {  1 2 3 4 5  } ;
004017B0    Next Line

 

3. Swich

switch(i) {
 case 0:
  //...
  break;
 case 1:
  //...
  break;
 default:
  //....
 }
// Next Line

28 :       switch(i) {
004017BF     mov          eax,dword ptr [ebp- 4 ]
004017C2     mov          dword ptr [ebp-30h],eax       将i的值放入临时变量中
004017C5     cmp          dword ptr [ebp-30h], 0          与0比较
004017C9     je           main+33h ( 004017d3 )           相等则跳转
004017CB     cmp          dword ptr [ebp-30h], 1          与1比较
004017CF     je           main+53h ( 004017f3 )
004017D1     jmp          main+73h ( 00401813 )
29 :       case  0 :
004017D3    //
30 :       break ;
004017F1     jmp          main+91h ( 00401831 )
31 :       case  1 :
004017F3    //
32 :       break ;
00401811     jmp          main+91h ( 00401831 )
33 :        default:
34 :           break ;
35 :       }                                         switch函数结束
36 :
47 :       //Next Line
00401831   

 





 

你可能感兴趣的:(代码)