编写一个两数交换函数swap,具体代码如下:
代码语言:javascript复制#include<stdio.h>
void swap(int *p1,int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2= temp;
//printf("p1=%d,p2=%d,temp=%dn",p1,p2,temp);
}
void main(){
int a=0;
int b=0;
char *str1="a=%d,b=%dn";
printf(" n");
a=2;
b=3;
printf(str1,a,b);
swap(&a,&b);
printf(str1,a,b);
}
首先对main函数进行汇编转换:
代码语言:javascript复制#include<stdio.h>
void swap(int *p1,int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2= temp;
//printf("p1=%d,p2=%d,temp=%dn",p1,p2,temp);
}
main(){
int a=0;
int b=0;
char *str1="a=%d,b=%dn";
printf(" n");
_asm{
//a=2
mov a,2
//b=3
mov b,3
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
//swap(&a,&b);
lea eax,b
push eax
lea ecx,a
push ecx
call swap
add esp,8
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
}
}
现在需要将swap也转化为汇编,并放入main函数中,具体思路如下:
1、先对swap函数反汇编,并删除ret指令,
注明:swap函数大致处理过程为:把下个地址压入堆栈,然后参数入栈,然后把所有寄存器压入堆栈,分配空间,空间清C然后变量赋值开始程序然后做堆栈平衡清理堆栈
代码语言:javascript复制void swap(int *p1,int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2= temp;
}
swap:
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
lea edi,[ebp-44h]
mov ecx,11h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
mov eax,dword ptr [ebp 8]
mov ecx,dword ptr [eax]
mov dword ptr [ebp-4],ecx
mov edx,dword ptr [ebp 8]
mov eax,dword ptr [ebp 0Ch]
mov ecx,dword ptr [eax]
mov dword ptr [edx],ecx
mov edx,dword ptr [ebp 0Ch]
mov eax,dword ptr [ebp-4]
mov dword ptr [edx],eax
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
PS:这里为什么要删掉
代码语言:javascript复制swap:
ret
因为不删除swap:和ret,那这个汇编表示就是一个函数,而我们知道
代码语言:javascript复制#include<stdio.h>
void main(){
void swap(int *p1,int *p2)
{
//xxxx;
}
}
这个定义是非法的,即错误的函数定义。
所以删除swap:和ret后,main里面不再是一个完整的函数,但是又保留了该swap函数的基本功能(即,把下个地址压入堆栈,然后参数入栈,然后把所有寄存器压入堆栈,分配空间,空间清C然后变量赋值开始程序然后做堆栈平衡清理堆栈)。
2、将1中的汇编代码替换掉call swap,
代码语言:javascript复制#include<stdio.h>
main(){
int a=0;
int b=0;
char *str1="a=%d,b=%dn";
printf(" n");
_asm{
//a=2
mov a,2
//b=3
mov b,3
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
//swap(&a,&b);
lea eax,b
push eax
lea ecx,a
push ecx
//call swap
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
lea edi,[ebp-44h]
mov ecx,11h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
mov eax,dword ptr [ebp 8]
mov ecx,dword ptr [eax]
mov dword ptr [ebp-4],ecx
mov edx,dword ptr [ebp 8]
mov eax,dword ptr [ebp 0Ch]
mov ecx,dword ptr [eax]
mov dword ptr [edx],ecx
mov edx,dword ptr [ebp 0Ch]
mov eax,dword ptr [ebp-4]
mov dword ptr [edx],eax
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
add esp,8
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
}
}
3、调整替换的swap汇编
代码语言:javascript复制#include<stdio.h>
main(){
int a=0;
int b=0;
char *str1="a=%d,b=%dn";
printf(" n");
_asm{
//a=2
mov a,2
//b=3
mov b,3
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
//swap(&a,&b);
lea eax,b
push eax
lea ecx,a
push ecx
//call swap
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
lea edi,[ebp-44h]
mov ecx,11h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
mov eax,dword ptr [ebp 4h] //取p1的值,即a的地址 edp 4h,此时不能再使用a这个变量的汇编地址了,因为此时的ebp已经不再是main的ebp
mov ecx,dword ptr [eax] //将a的值赋给ecx
mov dword ptr [ebp-4],ecx //temp=a=2
mov edx,dword ptr [ebp 4h] //取p1的值,即a的地址
mov eax,dword ptr [ebp 8h] //取p2的值,即b的地址
mov ecx,dword ptr [eax] //取b的值3
mov dword ptr [edx],ecx //a=b=3
mov edx,dword ptr [ebp 8h] //取p2的值,即b的地址
mov eax,dword ptr [ebp-4] //取temp的值2
mov dword ptr [edx],eax //b=temp=2
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
add esp,8
//printf(str1,a,b);
mov ecx,b
push ecx
mov eax,a
push eax
mov edx,str1
push edx
call printf
add esp,12
}
}
完成!