编译器:理解小程序生成的汇编代码

2024-01-10

我正在自学编译器是如何工作的。我正在通过阅读反汇编来学习GCC从小型 64 位 Linux 程序生成代码。

我写了这个C程序:

#include <stdio.h>

int main()
{
    for(int i=0;i<10;i++){
        int k=0;
    }
}

使用 objdump 后我得到:

00000000004004d6 <main>:
  4004d6:       55                      push   rbp
  4004d7:       48 89 e5                mov    rbp,rsp
  4004da:       c7 45 f8 00 00 00 00    mov    DWORD PTR [rbp-0x8],0x0
  4004e1:       eb 0b                   jmp    4004ee <main+0x18>
  4004e3:       c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  4004ea:       83 45 f8 01             add    DWORD PTR [rbp-0x8],0x1
  4004ee:       83 7d f8 09             cmp    DWORD PTR [rbp-0x8],0x9
  4004f2:       7e ef                   jle    4004e3 <main+0xd>
  4004f4:       b8 00 00 00 00          mov    eax,0x0
  4004f9:       5d                      pop    rbp
  4004fa:       c3                      ret    
  4004fb:       0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]

现在我有一些疑问。

  1. 那是什么NOP在最后,为什么它在那里? (结盟?)

  2. 我正在编译gcc -Wall <program.c>。为什么我没有收到警告control reaches end of non-void function?

  3. 为什么编译器不在堆栈上分配空间sub rsp,0x10?为什么不使用rbp寄存器用于引用本地堆栈数据?

    PS:如果我调用一个函数(比如printf) 在里面for循环,为什么编译器突然生成sub rsp,0x10?为什么它仍然引用本地数据rsp登记。我希望生成的代码能够引用本地堆栈数据rbp!


关于第二个问题,既然C99标准允许没有明确的return 0 in the main函数,编译器会隐式添加它。请注意,这仅适用于main功能,没有其他功能。

至于第三个问题,rbp寄存器充当帧指针 https://en.wikipedia.org/wiki/Call_stack#FRAME-POINTER.

最后是PS。被调用的函数很可能正在使用16 bytes (0x10) 作为传递给函数的参数。减法就是从堆栈中“删除”这些变量。它可能是作为参数传递的两个指针吗?

如果您正在认真学习编译器的一般工作原理,并且可能想创建自己的编译器(这很有趣!:)),那么我建议您投资一些有关其理论和实践的书籍。龙之书 https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools是任何程序员书架上的绝佳补充。

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

编译器:理解小程序生成的汇编代码 的相关文章

  • 分段错误(核心转储)错误

    我的程序编译罚款 但在输入文件时出现 分段错误 核心转储 错误 我没有正确处理 ostream 吗 include
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • 在 C# Winforms 应用程序中嵌入 Windows XP 主题

    我有一个旧版 C Windows 窗体应用程序 其布局是根据 Windows XP 默认主题设计的 由于需要将其作为 Citrix 应用程序进行分发 该应用程序现在看起来像经典主题应用程序 因为 Citrix 不鼓励使用主题系统服务 所以
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • 使用 HTMLAgilityPack 从节点的子节点中选择所有

    我有以下代码用于获取 html 页面 将网址设置为绝对 然后将链接设置为 rel nofollow 并在新窗口 选项卡中打开 我的问题是关于将属性添加到 a s string url http www mysite com string s
  • 在 C++17 中使用 成员的链接错误

    我在 Ubuntu 16 04 上使用 gcc 7 2 并且需要使用 C 17 中的新文件系统库 尽管确实有一个名为experimental filesystem的库 但我无法使用它的任何成员 例如 当我尝试编译此文件时 include
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • Android 中 EditText 的不同颜色

    我正在尝试使 EditText 的文本具有多种颜色 例如 如果我的文本是 It is a good day 是否可以将句子的 It is a 部分设置为绿色 其余部分设置为红色 我用类似的东西使我的颜色的某些部分变成绿色 final Str
  • 使用 Ninject 具有多个参数的构造函数

    我正在尝试使用Ninject http www ninject org 作为 IoC 容器 但无法理解如何创建在构造函数中具有超过 1 个参数的类的实例 基本上 我有一个用于在 PCL 库中进行身份验证的服务接口 及其在 WP8 项目中的实
  • 我应该使用什么协议来进行快速命令/响应交互?

    我需要建立一个用于快速命令 响应交互的协议 我的直觉告诉我只需将一个简单的协议与 CRLF 分隔的 ascii 字符串拼凑在一起 就像 SMTP 或 POP3 的工作方式一样 如果我需要保护它 则可以通过 SSH SSL 对其进行隧道传输
  • PHP 是否优化尾递归?

    我写了一小段代码 我相信如果尾递归被优化的话应该会成功 但是它炸毁了堆栈 我应该得出 PHP 没有优化尾递归的结论吗 function sumrand n sum if n 0 return sum else return sumrand
  • C#,后台工作者

    我有一个示例 WinForms 应用程序 它使用BackgroundWorker成分 它工作正常 但是当我点击Cancel按钮取消后台线程 但它不会取消线程 当我击中Cancel呼叫按钮 CancelAsync 方法 然后在RunWorke
  • Facebook 示例拼图:河内塔

    这是 Facebook 招聘样本测试中的一个问题 有 K 个钉子 当从桩的底部到顶部观察时 每个桩可以按半径递减的顺序容纳圆盘 有N个圆盘 半径为1到N 给定钉子的初始配置和钉子的最终配置 输出从初始配置转换到最终配置所需的移动 您需要以最
  • pandas 混合位置和标签索引,无需链接

    Since ix已经自 Pandas 0 20 起已弃用 http pandas docs github io pandas docs travis whatsnew html deprecate ix 我想知道在 Pandas 中混合基于
  • 是否可以调整嵌入的 .mov 的大小?

    我嵌入的 mov 剪辑有时比显示它的位置大 所以我想调整剪辑的大小 曾尝试过width and height但这只会改变显示它的区域 它不会调整实际电影的大小 可以调整影片大小吗 如果是 怎么办 是的 您需要scale属性 有 QuickT
  • 如何从aspx页面中抓取图像?

    我在尝试着scrape来自 aspx 页面的图像 我有这段代码 可以从普通网页中抓取图像 但无法抓取 aspx 页面 因为我需要将 http post 请求发送到 aspx 页面 即使在阅读了几个线程之后 我也不知道如何做到这一点是原来的代
  • 使用蓝牙 LE 在 iOS 和 Android 之间进行通信

    我有一个工作应用程序 使用 CoreBluetooth 在 iPad 中央 和 iPhone 外围 之间进行通信 我有一项服务有两个特点 我的 Nexus 7 运行最新的 Android 4 3 支持 BTLE Android 加入 BTL
  • 给定中序和后序遍历,如何输出树的前序遍历?

    给出当我在整数数组中具有先序和中序遍历时输出树的后序遍历的代码 如何使用给定的中序和后序数组来类似地获取前序 void postorder int preorder int prestart int inorder int inostart
  • 手势字符识别

    I use Dio dictionary function gesture on screen get text to search Library that in Android can make to be the function o
  • 如何使用 SI 符号格式化 noUiSlider 的刻度标签?

    这是我的 noUiSlider 的样子 我想将刻度标签格式设置为 1000 gt 1K 900000 gt 900K 5000000 gt 5M 等 即用适当的 SI 符号缩写数字 library shiny library shinyWi
  • function '<-'/2 undefined 接收块中出现错误 Elixir

    这是我的 Elixir 代码 defmodule ErlProcess do def receiver do receive do sayHello msg gt sender lt ok ok end end end 但它给出了这个错误
  • NVM无法在ubuntu 18.04上安装nodejs

    我尝试在 ubuntu 18 04 上使用 nvm 安装nodejs 但每次它都会抛出以下错误堆栈 pasindu pasindu HP EliteBook 850 G7 Notebook PC nvm install 0 10 35 Do
  • 关于端点接口的 jax-ws

    使用注释定义了 Java 接口 网络服务编译了代码 一切顺利 Example WebService public interface HelloWorldIfc 现在我尝试将端点接口定义为 WebService endpointInterf
  • 是否有一个简单的 Bugzilla/Trac 客户端供非软件人员使用?

    我知道这不完全是一个编程问题 但它直接影响我们的开发人员和我们分配编写的代码 如果有另一个类似的论坛可以更好地发布这个问题 请告诉我 我会从这里记下这个问题并将其发布到那里 我们的工作环境是几个开发人员为工厂生产车间创建 20 30 和维护
  • JavaFX 项目结构

    JavaFX 使用 FXML 的 MVC 模型听起来很棒 但我在找出如何组织我的项目包时遇到了困难 我发现的关于 JavaFX 的每一个教程都太简单且无组织 他们只是创建一个包并在那里创建所有内容 每个控制器 每个 fxml 每个 css
  • 如何在属性文件的数值中包含 _ ?

    我怎样才能拥有 下划线 在我的数值属性中 同时注入 ValueSpring中的注解 如果我包括 按照我的价值观 Spring 会抛出TypeMismatchException properties 文件 min score 20 000 j
  • 编译器:理解小程序生成的汇编代码

    我正在自学编译器是如何工作的 我正在通过阅读反汇编来学习GCC从小型 64 位 Linux 程序生成代码 我写了这个C程序 include