push ebp ;ebp入栈
mov ebp, esp ;因为esp是堆栈指针,无法暂借使用,所以得用ebp来存取堆栈
sub esp, 4*5 ;下面的wsprintf一共使用了5个参数,每个参数占用4个字节,所以要入栈4*5个字节
push 1111
push 2222
push 3333
push offset szFormat
push offset szOut
call wsprintf ;调用wsprintf
add esp, 4*5 ;堆栈使用完毕,“还”回4*5个字节给系统
...
mov esp, ebp ;恢复esp的值
pop ebp ;ebp出栈
我不明白:
对esp先是
sub esp,4*5,
最后再
add asp,4*5
这样esp的值不是已恢复了吗,为什么前面还要
mov ebp,
然后后面又要
esp mov esp, ebp
?
6 个解决方案
#1
主要是为了防止子程中的误操作导致堆栈失衡吧. sub esp, 4*5 和 add esp, 4*5 仅仅是就调用 wsprintf 函数来的. 其他可能还有涉及到堆栈的操作的.
另外, 趁着还没有人回复, 自己把另外的两个帖子给删了吧, 不会有不良影响的, 是网页响应慢多点了几下回复的?
另外, 趁着还没有人回复, 自己把另外的两个帖子给删了吧, 不会有不良影响的, 是网页响应慢多点了几下回复的?
#2
这个是一个历史问题。
注意,由于这段代码是由编译器生成的。所以,不存在什么“误操作导致堆栈失衡”的问题。我刚才临时查了一下,在一篇讲Eudora 4.3.0.46的修改的文章里提到,Eudora里有这样的代码:MOV AL,[ESP+08]。这样,文章里的“无法暂借使用”也说不通的。
原因和Borland的Turbo Pascal有关
熟悉Turbo Pascal的人都知道,在编译以后的Pascal程序里,子程序的开头都有下面的语句
push bp
mov bp,sp
实际上,这个就是pascal的标准调用框架。因为在pascal的过程和函数里,对堆栈参数的访问是通过bp进行的。这个是borland的约定。pascal约定的影响相当广泛,从这段程序就可以看出来。
注意,由于这段代码是由编译器生成的。所以,不存在什么“误操作导致堆栈失衡”的问题。我刚才临时查了一下,在一篇讲Eudora 4.3.0.46的修改的文章里提到,Eudora里有这样的代码:MOV AL,[ESP+08]。这样,文章里的“无法暂借使用”也说不通的。
原因和Borland的Turbo Pascal有关
熟悉Turbo Pascal的人都知道,在编译以后的Pascal程序里,子程序的开头都有下面的语句
push bp
mov bp,sp
实际上,这个就是pascal的标准调用框架。因为在pascal的过程和函数里,对堆栈参数的访问是通过bp进行的。这个是borland的约定。pascal约定的影响相当广泛,从这段程序就可以看出来。
#3
这样用ebp来寻址堆栈中的参数比较方便,因为进栈出栈操作会改变esp的值,如果用esp来寻值,原来esp+n的参数现在就会改变,可能是esp+n+2,或者esp+n-2
#4
基本是这样的
特别是在里面有分支的时候,用esp有时就很讨厌。
特别是在里面有分支的时候,用esp有时就很讨厌。
#5
先保存调用者的栈底地址,然后用调用者的栈顶作为自己的栈底,从此开始自己栈的生长(有些书称此行为为打开堆栈)。
sub esp, 4*5
是为了开辟一个可以存放5个双字的空间以便存储其自己的push和pop
那么后面的3个操作跟上面的3个是成对的,意思就比较明白了
以上是我的理解。
#6
该说的上面的帅哥们都说了~~我也不用多说了~~
#1
主要是为了防止子程中的误操作导致堆栈失衡吧. sub esp, 4*5 和 add esp, 4*5 仅仅是就调用 wsprintf 函数来的. 其他可能还有涉及到堆栈的操作的.
另外, 趁着还没有人回复, 自己把另外的两个帖子给删了吧, 不会有不良影响的, 是网页响应慢多点了几下回复的?
另外, 趁着还没有人回复, 自己把另外的两个帖子给删了吧, 不会有不良影响的, 是网页响应慢多点了几下回复的?
#2
这个是一个历史问题。
注意,由于这段代码是由编译器生成的。所以,不存在什么“误操作导致堆栈失衡”的问题。我刚才临时查了一下,在一篇讲Eudora 4.3.0.46的修改的文章里提到,Eudora里有这样的代码:MOV AL,[ESP+08]。这样,文章里的“无法暂借使用”也说不通的。
原因和Borland的Turbo Pascal有关
熟悉Turbo Pascal的人都知道,在编译以后的Pascal程序里,子程序的开头都有下面的语句
push bp
mov bp,sp
实际上,这个就是pascal的标准调用框架。因为在pascal的过程和函数里,对堆栈参数的访问是通过bp进行的。这个是borland的约定。pascal约定的影响相当广泛,从这段程序就可以看出来。
注意,由于这段代码是由编译器生成的。所以,不存在什么“误操作导致堆栈失衡”的问题。我刚才临时查了一下,在一篇讲Eudora 4.3.0.46的修改的文章里提到,Eudora里有这样的代码:MOV AL,[ESP+08]。这样,文章里的“无法暂借使用”也说不通的。
原因和Borland的Turbo Pascal有关
熟悉Turbo Pascal的人都知道,在编译以后的Pascal程序里,子程序的开头都有下面的语句
push bp
mov bp,sp
实际上,这个就是pascal的标准调用框架。因为在pascal的过程和函数里,对堆栈参数的访问是通过bp进行的。这个是borland的约定。pascal约定的影响相当广泛,从这段程序就可以看出来。
#3
这样用ebp来寻址堆栈中的参数比较方便,因为进栈出栈操作会改变esp的值,如果用esp来寻值,原来esp+n的参数现在就会改变,可能是esp+n+2,或者esp+n-2
#4
基本是这样的
特别是在里面有分支的时候,用esp有时就很讨厌。
特别是在里面有分支的时候,用esp有时就很讨厌。
#5
先保存调用者的栈底地址,然后用调用者的栈顶作为自己的栈底,从此开始自己栈的生长(有些书称此行为为打开堆栈)。
sub esp, 4*5
是为了开辟一个可以存放5个双字的空间以便存储其自己的push和pop
那么后面的3个操作跟上面的3个是成对的,意思就比较明白了
以上是我的理解。
#6
该说的上面的帅哥们都说了~~我也不用多说了~~