【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
在编写代码的时候我们都会自己重新定义一个打印函数,为什么要这样呢?我想主要原因还是为了定义其中的打印开关。如果打开了开关,我们当然可以看到很多的打印信息,但是如果不需要这些信息,我们就可以关上这些开关,所以一般的打印函数函数都是可以自己定义的。
#include <stdio.h>
#include <windows.h>
void XiaoxingPrintf(char* str, ...)
{
char buffer[64];
va_list va;
va_start(va, str);
vsprintf(buffer, str, va);
va_end(va);
printf("%s\n", buffer);
}
int main(int argc, char* argv[])
{
XiaoxingPrintf(" argc = %d, &argv = 0x%x\n", argc, &argc);
return 1;
}
上面的这段代码其实也很平常,看上去没有什么特别之处,但是我们想知道,这个va究竟是个什么东西?不妨可以反汇编看一下,
7: void XiaoxingPrintf(char* str, ...)
8: {
0040D430 push ebp
0040D431 mov ebp,esp
0040D433 sub esp,84h
0040D439 push ebx
0040D43A push esi
0040D43B push edi
0040D43C lea edi,[ebp-84h]
0040D442 mov ecx,21h
0040D447 mov eax,0CCCCCCCCh
0040D44C rep stos dword ptr [edi]
9: char buffer[64];
10: va_list va;
11:
12: va_start(va, str);
0040D44E lea eax,[ebp+0Ch]
0040D451 mov dword ptr [ebp-44h],eax
13: vsprintf(buffer, str, va);
0040D454 mov ecx,dword ptr [ebp-44h]
0040D457 push ecx
0040D458 mov edx,dword ptr [ebp+8]
0040D45B push edx
0040D45C lea eax,[ebp-40h]
0040D45F push eax
0040D460 call vsprintf (0040d750)
0040D465 add esp,0Ch
14: va_end(va);
0040D468 mov dword ptr [ebp-44h],0
15:
16: printf("%s\n", buffer);
0040D46F lea ecx,[ebp-40h]
0040D472 push ecx
0040D473 push offset string "%s\n" (0042201c)
0040D478 call printf (0040d850)
0040D47D add esp,8
17: }
0040D480 pop edi
0040D481 pop esi
0040D482 pop ebx
0040D483 add esp,84h
0040D489 cmp ebp,esp
0040D48B call __chkesp (0040d710)
0040D490 mov esp,ebp
0040D492 pop ebp
0040D493 ret
上面的汇编代码很多,其实有用的信息并不多。首先我们看va_start这一句话,好像做的事情很简单,就是把ebp+0xc给了va,va本身占用了四个字节,也就是位于[ebp-44h]的位置。那么最后的va_end呢,也不复杂,也就是把[ebp-44h]的位置清零了一下。但是可虑到这里的va是一个临时变量,是否清零其实意义不大。那么,这里的ebp+0xc是什么意思呢?首先我们看到,ebp上面的数值是原来push
ebp的数值,ebp+4是函数的返回地址,ebp+8是str的地址,那么很明显,ebp+0xc就是第二个参数的地址。所以,我们可以对这个打印函数稍微改造一下,
void XiaoxingPrintf(char* str, ...)
{
char buffer[64];
vsprintf(buffer, str, &str + 1);
printf("%s\n", buffer);
}
同样一个函数,三句话就可以搞定了。不再需要记住那么多头文件和数据类型。当然,这背后需要你对函数堆栈、参数地址、ebp和esp理解得比较深刻和具体了。
分享到:
相关推荐
代码随想录-八股文 pdf
代码随想录知识星球精华(最强⼋股⽂) 这份PDF总结了 代码随想录知识星球 的全部精华内容,覆盖了⼏乎程序员学习必备的内容。 知识星球⾥很多录友拿到了⼤⼚offer,包括科班 和 ⾮科班的,⽽他们的每⽇学习总结都是...
代码随想录算法PDF.rar
代码随想录算法PDF.zip
代码随想录-大厂八股文-面试
代码随想录贪心算法知识,非常管用
代码随想录 面试大厂八股文 手撕代码必备神器
软件随想录全集
代码随想录的pdf版本,不知道为啥放在电脑上面光删除不掉,所以网上保存一下下!
00.代码随想录-最强八股文-第3版-无密版本.pdf
「代码随想录」动态规划专题精讲(v1.2).pdf
软件随想录 软件随想录 软件随想录 软件随想录 软件随想录
代码随想录知识星球精华-大厂面试八股文v1.1.pdf
付费渠道买的,请珍惜
软件随想录_扫描版_5.79M
软件随想录
计算机教育_软件随想录_给计算机专业学子的建议知识.pdf
「代码随想录」程序员求职攻略
软件随想录.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
软件随想录+程序员必读pdf,让一个团队中的所有人朝同一个方向齐心协力地工作经验谈.