首页
社区
课程
招聘
[旧帖] 哪位大神帮我解释一下汇编代码的第3句和第7句 0.00雪花
发表于: 2012-10-22 14:06 3445

[旧帖] 哪位大神帮我解释一下汇编代码的第3句和第7句 0.00雪花

2012-10-22 14:06
3445
#include <stdio.h>
int main()
{
	int a,b=5;
	scanf("%d",&a);
	if(a==0)
		a=8;
	return a+b;
}

汇编如下:
push   ecx                     ;
lea    eax , dword ptr [esp]   ;
push   eax                     ;
push   00407030                ;指向字符串"%d"
call   00401030                ;scanf
mov    eax , dword ptr[esp+8]  ;将输入的字符串传出 
add    esp , 00000008          ;平衡堆栈 
test   eax ,eax                ;
jne    00401020
mov    eax , 00000008
add    eax , 00000005
pop    ecx                    ;释放局部变量的内存,相当于add esp , 4 
ret 


第3句和第7句不明白,哪位大神帮我解释一下吧,先谢了

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 22
活跃值: (443)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
push   eax                     ;                               //参数 a 入栈 esp - 4
push   00407030                ;指向字符串"%d"  //参数%d 入栈 esp - 4

add    esp , 00000008          ;平衡堆栈          esp = esp + 8

应该是这样吧
2012-10-22 15:20
0
雪    币: 807
活跃值: (2228)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
push   ecx                     ;
lea    eax , dword ptr [esp]   ;
push   eax                     ;  函数调用参数1,入栈后,导致 esp - 4
push   00407030                ;  函数调用参数2,入栈后,导致 esp - 8
call   00401030                ;  scanf
mov    eax , dword ptr[esp+8]  ;  在平衡堆栈前先取出函数的输出结果;
add    esp , 00000008          ;  平衡堆栈,丢弃前面入栈的2个调用参数;
test   eax ,eax                ;
jne    00401020
mov    eax , 00000008
add    eax , 00000005
pop    ecx                     ;  释放局部变量的内存,相当于add esp , 4
ret
2012-10-22 16:48
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
建议看下《天书夜读》前几章
2012-10-22 17:14
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
回复错了不能删吗。。。。。。
2012-10-22 17:33
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
lea    eax , dword ptr [esp]   ;
push   eax                     ;

难道不是栈里的东西再次入栈吗?
另外  mov    eax , dword ptr[esp+8]  ;  在平衡堆栈前先取出函数的输出结果;
为什么是 +8  ?
2012-10-22 17:38
0
雪    币: 807
活跃值: (2228)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=千年之雪;1111317]lea    eax , dword ptr [esp]   ;
push   eax                     ;

难道不是栈里的东西再次入栈吗?
另外  mov    eax , dword ptr[esp+8]  ;  在平衡堆栈前先取出函数的输出结果;
为什么是 +...[/QUOTE]

lea    eax , dword ptr [esp]   ;

以上指令等效于:

mov    eax , esp

原程序只要改写一下就容易懂了:

push   ecx                     ;
mov    eax, esp                ;
push   eax                     ;  函数的输入参数1(指针,指向内存地址)
push   00407030                ;  函数的输入参数2(指针,指向内存地址)
call   00401030                ;  scanf 调用函数,得到键盘输入值
mov    eax , dword ptr[esp+8]  ;  从函数的输入参数1中将函数的处理结果取出
add    esp , 00000008          ;  堆栈平衡,使堆栈恢复到 scanf 函数调用前的状态
. . . . . .

    如果还看不明白,那就请向上帝祈祷吧,这个世界估计也只有他老人家能帮到你了。
2012-10-22 18:01
0
雪    币: 0
活跃值: (85)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=千年之雪;1111317]lea    eax , dword ptr [esp]   ;
push   eax                     ;

难道不是栈里的东西再次入栈吗?
另外  mov    eax , dword ptr[esp+8]  ;  在平衡堆栈前先取出函数的输出结果;
为什么是 +...[/QUOTE]

楼主这段话表示有两个疑问,咱们一一解决:
第一.楼主以为第一个push ecx指令是给scanf函数压栈,其实不是,而是为main函数预留的变量。但是main函数中明明有两个变量(a和b),为什么只预留一个变量?因为编译器给优化掉了;
第二.scanf函数是遵循C调用约定的,即堆栈平衡的责任归它的调用者,在这里main函数要负责平衡堆栈,这是楼主你贴出来的代码:
call   00401030                ;scanf
mov    eax , dword ptr[esp+8]  ;将输入的字符串传出
add    esp , 00000008          ;平衡堆栈
esp之所以要加8,是因为main函数还未对scanf进行扫尾工作,这三行代码可以这样转换:
call   00401030                ;scanf
add    esp , 00000008          ;平衡堆栈
mov    eax , dword ptr[esp]  ;将输入的字符串传出
这两种方式,逻辑完全相同。
望采纳
2012-10-23 20:45
0
游客
登录 | 注册 方可回帖
返回
//