首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >装配:功能模板冥想

装配:功能模板冥想
EN

Stack Overflow用户
提问于 2014-11-22 15:20:05
回答 1查看 73关注 0票数 0

我现在正在学习程序集,对于(大概)标准函数模板,我一点也不了解。

因此,基于这本很好的书,“函数要记住的表单如下:”

代码语言:javascript
运行
复制
function_label:
    pushl   %ebp
    movl    %esp, %ebp
    < normal function code goes here>
    movl    %ebp, %esp
    popl    %ebp
    ret

好吧,我对此很满意,但有一件事我不明白。在“正常函数代码”之后,我们恢复esp的初始(预调用)值,该值以前存储在ebp中。

现在,我清楚地理解了为什么我们要将esp值服务回调用上下文。我不明白的是,在什么条件下,esp值可以在函数的执行过程中被更改。

这是否是针对我们自己的某种保护(万一我们在代码中的某个地方破坏了堆栈)?或者,在函数中更改堆栈值是正常的做法?或者,即使我们不对其进行任何操作,初始esp值也可能在执行过程中发生更改?(事实上,我不知道这是怎么回事。)

在考虑这个问题时,我觉得很傻,并在这段简单的代码中用gdb检查了gdb值:

代码语言:javascript
运行
复制
.section .data
message:
    .asciz "> Hello from function #%d\n"

.section .text
.globl main

main:
    nop
    call    overhere
    pushl   $0
    call    exit
overhere:
    pushl   %ebp
    movl    %esp, %ebp
    pushl   $1
    pushl   $message
    call    printf
    add     $8, %esp
    movl    %ebp, %esp
    popl    %ebp
    ret 

esp (正如我所预期的)没有受到影响,因此将ebp迁移到esp并没有真正改变任何事情。

现在,我希望我想弄清楚的是:

  • esp值本身会发生变化吗?(我敢打赌它做不到。)
  • 如果它不能,那么上面的模板显然假设程序员可能会在函数中以某种方式改变它。但我不明白为什么在地球上人们可能需要这样做,所以-改变esp值是一个错误吗?

先谢谢你原谅我的无知。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-22 15:26:31

我感到困惑的是,您为什么忽略了显式更改espadd $8, %esp的指令。所以答案显然是肯定的,它可能在一个函数的过程中发生变化,而不是一个错误。注意,pushcall也改变了它,实际上add是为了补偿两个push指令( printf末尾的ret将平衡call)。更改esp的另一个典型原因是局部变量的分配。在您显示的函数模板中省略了这一点,它通常看起来就像sub $size_of_locals, %esp后面的movl %esp, %ebp

也就是说,您不需要使用ebp来记住堆栈指针,只要您确保它在函数出口处的值与输入时的值相同。最近版本的gcc在启用优化时不使用ebp,否则可以使用-fomit-frame-pointer进行优化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27078970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档