为什么main在没有变量的情况下初始化堆栈帧

2023-12-04

为什么这段代码:

#include "stdio.h"
int main(void) {
    puts("Hello, World!");
}

决定初始化堆栈帧?这是汇编代码:

.LC0:
        .string "Hello, World!"
main:
        push    rbp
        mov     rbp, rsp
        mov     edi, OFFSET FLAT:.LC0
        call    puts
        mov     eax, 0
        pop     rbp
        ret

为什么编译器初始化一个堆栈帧只是为了稍后将其销毁,而不使用它?这肯定不会在主函数外部导致任何错误,因为我从不使用堆栈,所以我不会导致任何错误。为什么要这样编译呢?


在每个编译函数中包含这些步骤是编译器的“基线”,未经优化。拆解后看起来很干净,而且很有道理。但是,编译器可以优化输出以减少没有实际效果的代码的开销。您可以通过使用不同的优化级别进行编译来看到这一点。

你得到的就像this:

.LC0:
  .string "Hello, World!"
main:
  push rbp
  mov rbp, rsp
  mov edi, OFFSET FLAT:.LC0
  call puts
  mov eax, 0
  pop rbp
  ret

这是在 GCC 中编译的,没有任何优化。

添加标志 -O4 给出this output:

.LC0:
  .string "Hello, World!"
main:
  sub rsp, 8
  mov edi, OFFSET FLAT:.LC0
  call puts
  xor eax, eax
  add rsp, 8
  ret

您会注意到,这仍然会移动堆栈指针,但它会跳过更改基指针,并避免与之相关的耗时的内存访问。

假定堆栈在 16 字节边界上对齐。返回地址已被压入后,还需要减去另外 8 个字节才能到达函数调用之前的边界。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么main在没有变量的情况下初始化堆栈帧 的相关文章

随机推荐

  • 彩色 grep — 查看整个文件并突出显示匹配项

    I find grep s color always标志非常有用 但是 grep 仅打印匹配的行 除非您要求上下文行 鉴于它打印的每一行都有一个匹配项 突出显示并没有增加尽可能多的功能 我真的很想cat文件并查看整个文件 其中模式匹配突出显
  • 如何在批处理文件中使用 if - else 结构?

    我有一个关于批处理文件中的 if else 结构的问题 每个命令单独运行 但我无法安全地使用 if else 块 因此我的程序的这些部分不起作用 我怎样才能使这些部件运行 谢谢 IF F 1 IF C 1 copying the file
  • 如何在node js中使用scp2将文件复制到远程服务器?

    我想使用 Node js 将文件从本地服务器复制到远程服务器scp2包裹 首先 使用文件上传到本地服务器multer之后将该文件复制或移动到远程服务器 My Code exports newFileUpload function req r
  • 我怎样才能告诉程序停止使用 freopen

    我是 C 初学者 我有一个问题超出了我的极限 我在 GNU GCC 下编译 我用 include
  • 重置部分应用程序设置

    所以 我有一个名为 Preferences 的表格TabControl在里面 这TabControl包含几个TabPages 常规 高级 杂项 带有少量组合框 复选框和标签 TabPage 内的每个控件都被分配应用程序设置属性绑定 又名它们
  • setTimeout 如何防止潜在的堆栈溢出

    一个例子 var list readHugeList var nextListItem function var item list pop if item setTimeout nextListItem 0 this line 如何使用s
  • 将 SHA1 转换为正常形式

    我有一个数据库 其中每个密码都是通过 SHA1 传递的 有时 我想去用户仪表板看看感觉如何 有没有办法 我可以将 SHA1 转换为正常形式以用于测试目的 谢谢 如果 正常形式 的意思是 我可以检索创建给定哈希的字符串 那么答案是否定的 它应
  • mkdir() 未将 chmod 设置为 0777

    为什么 mkdir 不将 CHMOD 设置为0777 mkdir var www test 0777 创建目录后 CHMOD 设置为0755 来自 php net bool mkdir string pathname int mode 07
  • 为什么根据我的 numpy 数组的类型是 int64 还是 uint8,按元素加法/减法的输出会有所不同?

    我正在进行图像比较并计算差异 并且注意到 仅当我使用 dtype int64 而不是 dtype uint8 作为 numpy 数组读取数据时 逐元素减法似乎才起作用 出于图像可视化的原因 我想切换到 unit8 image1 np arr
  • 将输出写入 Azure Functions 中的 Blob

    我正在学习使用 Azure 函数 所以 我可能听起来很愚蠢 我正在编写一个计时器触发函数 该函数每 1 分钟运行一次 添加两个数字并写入文件 这工作正常 因为我可以将输出写入本地服务器上的文件 第二步 我想将输出写入 blob 下面是代码
  • 如何使用 Swift Playground 打印到控制台?

    我一直在关注他们的新语言 swift 的 Apple Guide 但我不明白为什么右侧的栏只显示 Hello playground 而不是 Hello world 有人可以解释为什么println不是打印在右边吗 Playground no
  • 在sqlite中获取日期差异

    我想获得今天和到期日之间的日期差异 这是我实现的代码 但这并没有返回正确的输出 public String getDaysList Cursor cursor db query COUPON null null null null null
  • 理解 python id() 的唯一性

    Python 文档id 功能陈述如下 这是一个保证唯一且恒定的整数 该对象在其生命周期内 两个不重叠的对象 一生可能有相同的id value CPython实现细节 这是内存中对象的地址 虽然 下面的代码片段表明id的重复 由于我没有明确d
  • iPhone 的 CSS 媒体查询

    我有一个网站 该网站将使用媒体查询在桌面和 iPhone 上显示以提供不同的样式表 因此例如始终加载reset css 但如果在桌面上也加载desktop css 但如果在iPhone上 或者如果用户调整浏览器窗口的大小 改为加载 ipho
  • IE8 中 AJAX 的意外缓存结果

    我在 Internet Explorer 缓存 JQuery Ajax 请求结果时遇到严重问题 我的网页上有标题 每次用户导航到新页面时该标题都会更新 页面加载后我会这样做 get game getpuzzleinfo null funct
  • 从 ADUser DistinguishedName 获取 CN 值

    我有一个 PS 脚本 用于检查 Active Directory 中某些自定义用户的属性 属性之一是 经理 data Get ADUser user Properties Select Object DisplayName LockedOu
  • collections.sort方法仅用于List类型的集合吗?

    朋友们 我是 Java Collection 的新手 我想问一下Collections sort 方法仅用于 由集合使用List类型 我无法对以下代码进行排序 Collection collection new HashSet collec
  • Cosmos DB 查询 - 当某个属性不存在于所有文档中时使用 ORDER BY

    我们在为 Cosmos Document DB 编写查询时遇到问题 我们想要创建一个新的文档属性并在 ORDER BY 子句中使用它 例如 如果我们有一组文档 例如 Name Geoff Company Acme Name Bob Comp
  • 为什么字体较小时高度会增加?

    我有一个具有一定行高的块 我在其中插入内容 before伪元素 block before content text here 这效果很好 但是 如果我也给内容设置较小的字体大小 block before font size 6em cont
  • 为什么main在没有变量的情况下初始化堆栈帧

    为什么这段代码 include stdio h int main void puts Hello World 决定初始化堆栈帧 这是汇编代码 LC0 string Hello World main push rbp mov rbp rsp