重新学习一下汇编。
基友推荐的书《天书夜读-从汇编语言到Windows内核编程》
不但push、pop、call、ret会操作堆栈,sub和add也可以用于操作堆栈。如果我要一次在堆栈中分配4个4字节长整形
的空间,可以简单地把esp减去4*4=16即可。同样也可以用add指令来恢复它。这常常用于分配函数局部变量空间。
;函数------------------------------------------------------------------------------------
void myfunction(int a,int b)
{
int c=a+b;
}
int main(int argc,char** argv)
{
int a=0,b=0;
myfuntion(a,b);
return 0;
}
void myfunction(int a,int b)
{
push ebp ;保存ebp
mov ebp,esp ;此时ebp与esp相同 都是这次函数调用时的栈顶
sub esp,0CCh ;把esp往上移动一个范围 等于在堆栈中放出一片新的空间来存储局部变量
push ebx
push esi
push edi
;把局部变量区域初始化为,0CCCCCCCCh
;0CCh实际是int 3指令的机器码 这是一个断点中断指令
;因为局部变量不能被执行 如果被执行了 必然程序有错 这时发生中断来提示开发者
;这时vc编译debug版本的特有操作
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
int c=a+b;
mov eax,dword ptr [a]
add eax,dword ptr [b]
mov dword ptr [c],eax
}
pop edi
pop esi
pop ebx
mov esp,ebp ;恢复esp
pop ebp ;恢复ebp
ret
int main(int argc, char** argv)
{
push ebp
mov ebp,esp
sub esp,0D8h
push ebx
push esi
push edi
lea edi,[ebp-0D8h]
mov ecx,36h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
int a=0,b=0;
mov dword ptr [a],0
mov dword ptr [b],0
myfunction(a,b);
mov eax,dword ptr [b] ;b a两个参数压入堆栈 _cdecl
push eax
mov ecx,dword ptr [a]
push ecx
call myfunction (0B511B8h)
add esp,8 ;恢复堆栈
return 0;
xor eax,eax
}
pop edi
pop esi
pop ebx
add esp,0D8h
cmp ebp,esp
call @ILT+455(__RTC_CheckEsp) (0B511CCh)
mov esp,ebp
pop ebp
ret
;for------------------------------------------------------------------------------------
int myfunction(int a,int b)
{
int c=a+b;
int i;
for(i=0;i<50;i++)
{
c=c+i;
}
return c;
}
;同上 略
int i;
for(i=0;i<50;i++)
008A17D7 mov dword ptr [i],0
008A17DE jmp myfunction+39h (8A17E9h)
008A17E0 mov eax,dword ptr [i]
008A17E3 add eax,1
008A17E6 mov dword ptr [i],eax
008A17E9 cmp dword ptr [i],32h
008A17ED jge myfunction+4Ah (8A17FAh)
{
c=c+i;
008A17EF mov eax,dword ptr [c]
008A17F2 add eax,dword ptr [i]
008A17F5 mov dword ptr [c],eax
}
008A17F8 jmp myfunction+30h (8A17E0h)
return c;
008A17FA mov eax,dword ptr [c]
mov <循环变量>,<初始值>
jmp B ;跳到第一次循环处
A:
修改循环变量
B: cmp <循环变量>,<限度变量>
jge 大于等于时跳出循环
{
循环体
}
jmp A
;while------------------------------------------------------------------------------------
int c=0;
008417D5 mov dword ptr [c],0
while(c<100)
008417DC cmp dword ptr [c],64h
008417E0 jge myfunction+3Dh (8417EDh)
{
c=c+i;
008417E2 mov eax,dword ptr [c]
008417E5 add eax,dword ptr [i]
008417E8 mov dword ptr [c],eax
}
008417EB jmp myfunction+2Ch (8417DCh)
return c;
008417ED mov eax,dword ptr [c]
A:cmp <循环变量>,<限制变量>
jge B
循环体 处理循环变量
.......
jmp A
B: 循环结束
;if-else if -else------------------------------------------------------------------------------------
if (c>0&&c<10)
003A33BD cmp dword ptr [c],0
003A33C1 jle myfunction+62h (3A33E2h) ;不满足直接跳到else if
003A33C3 cmp dword ptr [c],0Ah
003A33C7 jge myfunction+62h (3A33E2h)
{
printf("c>0");
003A33C9 mov esi,esp
003A33CB push offset string "c>0" (3A573Ch)
003A33D0 call dword ptr [__imp__printf (3A82B4h)]
003A33D6 add esp,4
003A33D9 cmp esi,esp
003A33DB call @ILT+455(__RTC_CheckEsp) (3A11CCh)
003A33E0 jmp myfunction+9Eh (3A341Eh) ;跳到if-else if-else 结束处
}
else if(c>10 &&c<100)
003A33E2 cmp dword ptr [c],0Ah
003A33E6 jle myfunction+87h (3A3407h) ;不满足 直接跳到printf("error")处
003A33E8 cmp dword ptr [c],64h
003A33EC jge myfunction+87h (3A3407h)
{
printf("c>10 &&c<100");
003A33EE mov esi,esp
003A33F0 push offset string "c>10 &&c<100" (3A57A8h)
003A33F5 call dword ptr [__imp__printf (3A82B4h)]
003A33FB add esp,4
003A33FE cmp esi,esp
003A3400 call @ILT+455(__RTC_CheckEsp) (3A11CCh)
}
else
003A3405 jmp myfunction+9Eh (3A341Eh)
;直接跳到结尾处
;因为else if处不满足的话已经跳到printf("error")了
;同样结构也适用于 if-else
{
printf("error");
003A3407 mov esi,esp
003A3409 push offset string "error" (3A57A0h)
003A340E call dword ptr [__imp__printf (3A82B4h)]
003A3414 add esp,4
003A3417 cmp esi,esp
003A3419 call @ILT+455(__RTC_CheckEsp) (3A11CCh)
}
return c;
003A341E mov eax,dword ptr [c]
;switch-case------------------------------------------------------------------------------------
switch(c)
00B9341E mov eax,dword ptr [c]
00B93421 mov dword ptr [ebp-0DCh],eax
00B93427 cmp dword ptr [ebp-0DCh],0 ;[c]和0比较
00B9342E je myfunction+0BBh (0B9343Bh) 相等跳到printf("c>0")
00B93430 cmp dword ptr [ebp-0DCh],1
00B93437 je myfunction+0D4h (0B93454h)
00B93439 jmp myfunction+0EBh (0B9346Bh)
{
case 0:
printf("c>0");
00B9343B mov esi,esp
00B9343D push offset string "c>0" (0B9573Ch)
00B93442 call dword ptr [__imp__printf (0B982B4h)]
00B93448 add esp,4
00B9344B cmp esi,esp
00B9344D call @ILT+455(__RTC_CheckEsp) (0B911CCh)
break;
00B93452 jmp myfunction+0EBh (0B9346Bh) ;break 跳到结尾处
case 1:
printf("c>10&&c<100");
00B93454 mov esi,esp
00B93456 push offset string "c>10&&c<100" (0B95808h)
00B9345B call dword ptr [__imp__printf (0B982B4h)]
00B93461 add esp,4
00B93464 cmp esi,esp
00B93466 call @ILT+455(__RTC_CheckEsp) (0B911CCh)
break;
}
return c;
00B9346B mov eax,dword ptr [c]