如nasm与c
用nasm调用c时
当然定义c函数,在nasm里用关键字extern来定义这个函数名,以便让汇编认识他(有些编译器会把c函数名前加上"_")
如
extern cstart
global _start ;不知道不用管
_start: ;不知道不用管
call cstart
c函数如:
void cstart(int a,int b,int c)
{
a=1;
c=3;
b=2;
}
在运行到call start的时候 调试时产生的汇编代码如:
call .**********(该函数的地址) ;esp=0x00011800
push ebp ;esp=0x000117fc
mov ebp,esp ;esp=0x000117f8,ebp=0x000117f8
mov dword ptr ss:[ebp+0x8], 0x00000001 ;esp=0x000117f8,ebp=0x000117f8
mov dword ptr ss:[ebp+0x10], 0x00000003 ;esp=0x000117f8,ebp=0x000117f8
mov dword ptr ss:[ebp+0xc], 0x00000002 ;esp=0x000117f8,ebp=0x000117f8
pop ebp
用call调用时esp位0x00011800,注意了这里的a,b,c其实不再栈里,是我自己添加进去的,如果你不是在汇编里直接call,而是在c函数里直接调用cstart(1,2,3)像这样的话它就会把a,b,c三个参数压入栈。但是可以看见c函数不管是之前你确实把参数压栈了还是没有,他照样这样计算。
我们要知道这么一个东西,就是这里的获取栈里的内容是怎么获取的,dword ptr ss:[0x000117f8]获取的内容就是ebp,他是以一个基地址(姑且这么说)加上长度,前面的dword,总之,大概意思就是这样的。所以啊ebp+0x10就是0x00011808,你看,他不正是c的“基地址”嘛?对吧 。 前面都说了,这里的a,b,c是我自己一相情愿加进去的。