最近在搞C和汇编混合编程,对栈平衡有点小理解,记录一下
- 当我们调用一个API或者子程序时时,API和子程序可以理解为函数,我们不必在返回的时候平衡栈里面的函数参数,但C语言库函数要我们自己平衡栈数据,
比如下面的程序:
#include "stdio.h"
#include "windows.h"int main(int argc, char* argv[])
{printf("begin\n");HINSTANCE libHandle;char *dll="user32.dll";libHandle=LoadLibrary(dll);__asm{xor ebx,ebxpush ebxpush 0x61626364push 0x65666768mov eax,esppush ebxpush eaxpush eaxpush ebx mov eax,dword ptr[MessageBox]call eax//mov esp,0x450add esp,12}return 0;
}
这段程序的功能是弹出MessageBox,我们最后平衡栈数据用到add esp,12,为什么是12呢?一共push了7次,应该是28啊!因为在stacall标准中,我们是不用考虑MessageBox参数的,MessageBox一共4个参数,
push ebxpush eaxpush eaxpush ebx
这4个push是不用我们管得,所以是12。但有一个我们要注意就是wsprintf,这个需要我们自己去平衡栈里面的参数数据
下面是调试的结果:
在运行到push 0x65666768,esp的值是
当运行完call eax,esp的值
两个值是相同的
调用C语言库函数时:
#include "stdio.h"
int main(){char *str="hello\n";__asm{push strcall printf}return 0;
}
- 进入asm和出asm时,esp的值要相同。比如说,我们程序进入__asm后,esp的值是0,那么在出asm时,一定要让esp的值变成0。
上面的程序,假设执行 xor ebx,ebx前,esp=0,当我们出asm时,esp的值一定要为0,不然会报错,上面的add esp,12就是这个目的,如果我们把这个去掉,在运行,就会报下面的错误
在举个例子:
int main(){__asm{push 0;}return 0;
}
这段程序也会报上面的错误
写在最后:
这些是和同学讨论出来的,如果有什么不对的地方希望指出来
自己很菜,在学了点汇编后,自己摸索C和汇编混合编程的,很多东西还不懂,会继续努力的。
以后会继续补充