能力值:
( LV2,RANK:10 )
|
-
-
2 楼
push eax ; //参数 a 入栈 esp - 4
push 00407030 ;指向字符串"%d" //参数%d 入栈 esp - 4
add esp , 00000008 ;平衡堆栈 esp = esp + 8
应该是这样吧
|
能力值:
( 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
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
建议看下《天书夜读》前几章
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
回复错了不能删吗。。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
lea eax , dword ptr [esp] ;
push eax ;
难道不是栈里的东西再次入栈吗?
另外 mov eax , dword ptr[esp+8] ; 在平衡堆栈前先取出函数的输出结果;
为什么是 +8 ?
|
能力值:
( 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 函数调用前的状态
. . . . . .
如果还看不明白,那就请向上帝祈祷吧,这个世界估计也只有他老人家能帮到你了。
|
能力值:
( 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] ;将输入的字符串传出
这两种方式,逻辑完全相同。
望采纳
|
|
|