关键一句:以C语言为母语的程序员,常常
找一些汇编语言改写为C语言,是学习汇编
的快捷方式之一。
一,for循环
int myfunction(int a,int b)
{
int c=a+b;
int i;
for(i=0;i<50;i++)
{
c=c+i;
}
return c;
}
for(i=0;i<50;i++)
dword ptr [i],0
myfunction+39h (412BD9h)
00412BD0h eax,dword ptr [i]
eax,1
dword ptr [i],eax
00412BD9h dword ptr [i],32h
jge myfuntion+4Ah (412BEAh) ;jge指令,两数比较,前者大于等于后者则跳转
{
c=c+i;
mov eax,dword ptr [c]
add eax,dword ptr [i]
mov dword ptr [c],eax
}
jmp myfuntion+30h (412BD0h)
00412BEAh mov eax,dword ptr [c]
反汇编后的结构大意:
mov <循环变量>,<初始值> ;给循环变量赋初值
jmp B ;跳到第一次循环处
A:(改动循环变量) ;修改循环变量
……
B:cmp <循环变量>,<限制变量> ;检查循环条件
jge 跳出循环
(循环体)
……
jmp A ;跳回去修改循环变量
二,do循环
do{
c=c+1;
00411A55h mov eax,dword ptr [c]
add eax,dword ptr [i]
mov dword ptr [c],eax
}while(c<100);
cmp dword ptr [c],64h
jl myfunction+35h (411A55h) ;汇编语言中条件转移语句:JL/JNGE, 用于有符号数的条件转移指令,小于\不大于且不等于转移;
return c;
……
三,while循环
while(c<100){
00411A55h cmp dword ptr [c],64h
jge myfuntion+64h (411A66h)
c=c+1;
mov eax,dword ptr [c]
add eax,dword ptr [i]
00411A64h mov dword ptr [c],eax
}
jmp myfuntion+35h (411A55h)
四,if-else判断分支
if(c>0&&c<10)
{
printf("c>0");
}
else if(c>10&&c<10)
{
printf("c>10&&c<100");
}
else
{
printf("c>10&&c<100");
}
if(c>0&&c<10)
00411A66 cmp dword ptr [c],0
00411A6A myfunction+61h (411A81h)
00411A6C cmp dword ptr [c],0Ah
00411A70 jge myfunction+61h (411A81h)
{
printf("c>0");
00411A72 push offset string "c>0"(4240Dch)
00411A77 call @ILT+1300(_printf) (411519h)
00411A7C add esp,4
}
else if(c>10&&c<100)
00411A7F jmp myfunction+89h (411AA9h)
00411A81 cmp dword ptr [c],0Ah
00411A85 jle myfuntion+7ch (411A9Ch)
00411A87 cmp dword ptr [c],64h
00411A8B jge myfunction+7Ch (411A9ch)
五,switch-case判断分支
switch(c)
{
case 0:
printf("c>0");
case 1:
{
printf("c>10&&c<100");
break;
}
default:
printf("c>10&&c<100");
}
switch(c)
00411A66 mov eax,dword ptr [c]
00411A69 mov dword ptr [ebp-0E8h],eax
00411A6F cmp dword ptr [ebp-0E8h],0
00411A76 je myfuntion+63h (411A93h)
00411A78 cmp dword ptr [ebp-0E8h],1
00411A7F je myfuntion+70h (411A90h)
00411A81 jmp myfuntion+7Fh (411A9Fh)
case 0:
printf("c>0");
00411A83 push offset string "c>0"(4240DCh)
00411A88 call @ILT+1300(_printf)(411519h)
00411A8D add esp,4
case 1:
{
printf("c>10&&c<100");
00411A90 push offset string "c>10&&c<100"(424288h)
00411A95 call @ILT+1300(_printf)(411AACh)
00411A9A add esp,4
break;
00411A9D jmp myfunction+8Ch(411AACh)
}
default:
printf("c>10&&c<100");
00411A9F push offset string "c>10&&c<100"(424288h)
00411AA4 call @ITL+1300(_printf)(411519h)
00411AA9 add esp,4
}
六,C语言数组与结构
typedef struct{
int a;
int b;
int c;
}mystruct;
int myfunction(int a,int b)
{
unsigned char *buf[100];
mystruct *str=(mystruct *)buf;
int i;
for(i=0;i<5;i++)
{
strs[i].a=0;
strs[i].b=1;
strs[i].c=2;
}
return 0;
}
int i;
for(i=0;i<5;i=+)
mov dword ptr [i],0
jmp myfunction=45h (413695h)
00413686h mov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eax
00413695h cmp dword ptr [i],5
jge myfuntion+94h (4136E4h)
{
strs[i].a=0;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [strs]
mov dword ptr [ecx+eax],0
strs[i].b=1;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [strs]
;这里与.a不同,增加偏移量取得b的位置
mov dword ptr [ecx+eax+4],1
strs[i].c=2;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [strs]
mov dword ptr [ecx+eax+8],2
}
jmp myfunction+36h(413686h)
004136E4 xor eax,eax
imul这个指令令人想到结构体数组,这是一个特征。程序在访问一个结构体的数组时,往往需要得到数组中某个结构体元素的开始地址。很显然,某个元素的起始位置=下标*单个元素的长度+数组的起始地址。
七,C语言的共用体和枚举类型
typedef enum{
ENUM_1=1,
ENUM_2=2,
ENUM_3,
ENUM_4,
}myenum;
typedef struct{
int a;
int b;
int c;
}mystruct;
typedef union{
mystruct s;
myenum e[3];
}myunion;
int myfunction(int a,int b)
{
unsigned char buf[100]={0};
myunion *uns=(myunion *)buf;
int i;
for(i=0;i<5;i++)
{
uns[i].s.a=0;
uns[i].s.b=1;
}
return 0;
}
for(i=0;i<5;i++)
mov dword ptr [i],0
jmp myfuntion+49h(411A69h)
00411A60 mov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eax
00411A69 cmp dword ptr [i],5
jge myfunction+83h(411AA3h)
{
uns[i].s.a=0;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [uns]
mov dword ptr [ecx+eax],0
uns[i].s.b=1;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [uns]
mov dword ptr [ecx+eax+4],1
uns[i].e[2]=ENUM_4;
mov eax,dword ptr [i]
imul eax,eax,0ch
mov ecx,dword ptr [uns]
mov dword ptr [ecx+eax+8],4
}
jmp myfunction+40h (411A60h)