为什么 gcc 在 main 的开头推送 %rbx ?

2023-12-19

最新版本的 gcc 正在生成对我来说没有意义的程序集。我没有使用任何优化来编译代码;但是,即使没有优化,此代码的某些部分也没有意义。

这是C源:

  #include <stdio.h>

   int main()
   {
     int a = 1324;
     int b = 5657;
     int difference = 9876;
     int printf_answer = 2221;

     difference = a - b;

     printf_answer = printf("%d + %d = %d\n", a, b, difference);

     return difference;
   }

它产生这个程序集:

    .file   "exampleIML-1b.c"
    .section    .rodata
.LC0:
    .string "%d + %d = %d\n"
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    pushq   %rbx
    subq    $24, %rsp
    movl    $1324, -32(%rbp)
    movl    $5657, -28(%rbp)
    movl    $9876, -24(%rbp)
    movl    $2221, -20(%rbp)
    movl    -28(%rbp), %eax
    movl    -32(%rbp), %edx
    movl    %edx, %ecx
    subl    %eax, %ecx
    movl    %ecx, %eax
    movl    %eax, -24(%rbp)
    movl    $.LC0, %eax
    movl    -24(%rbp), %ecx
    movl    -28(%rbp), %edx
    movl    -32(%rbp), %ebx
    .cfi_offset 3, -24
    movl    %ebx, %esi
    movq    %rax, %rdi
    movl    $0, %eax
    call    printf
    movl    %eax, -20(%rbp)
    movl    -24(%rbp), %eax
    addq    $24, %rsp
    popq    %rbx
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)"
    .section    .note.GNU-stack,"",@progbits

有几件事没有意义:

(1) 为什么我们要推%rbx? %rbx 中有什么需要保存?

(2) 为什么我们在减法之前将 %edx 移动到 %ecx ?它不只是做什么sub %eax, %edx?

(3) 同样,为什么在存储值之前从 %ecx 移回 %eax ?

(4) 编译器将变量 a 放入内存位置 -32(%rbp)。除非我添加错误,否则 -32(%rbp) 不等于堆栈指针吗?不是所有局部变量都应该存储在值中吗少于当前堆栈指针?

我正在使用这个版本的 gcc:

[eos17:~/课程/CS451/IntelMachineLanguage]$ gcc -v 使用内置规格。 目标:x86_64-redhat-linux 配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique -object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/ jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj. jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 线程模型:posix gcc 版本 4.4.6 20120305(红帽 4.4.6-4)(GCC)


GCC dictates how the stack is used. Contract between caller and callee on x86:

    * after call instruction:
          o %eip points at first instruction of function
          o %esp+4 points at first argument
          o %esp points at return address 
    * after ret instruction:
          o %eip contains return address
          o %esp points at arguments pushed by caller
          o called function may have trashed arguments
          o %eax contains return value (or trash if function is void)
          o %ecx, %edx may be trashed
          o %ebp, %ebx, %esi, %edi must contain contents from time of call 
    * Terminology:
          o %eax, %ecx, %edx are "caller save" registers
          o %ebp, %ebx, %esi, %edi are "callee save" registers

main 函数与此上下文中的任何其他函数一样。海湾合作委员会决定使用ebx用于中间计算,因此它保留了其值。

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

为什么 gcc 在 main 的开头推送 %rbx ? 的相关文章

随机推荐

  • 在参数数组中传递整数数组

    我正在尝试在 pg promise 的参数数组中传递参数数组 如建议的那样pg promise 文档 https github com vitaly t pg promise wiki Learn by Example passing ar
  • C++奇怪的问题,未定义的引用

    出现错误 neljastest cpp 对 Vector2 Vector2 float float 的未定义引用 内尔贾斯特 cpp include
  • 注入 EntityManager 对比实体管理器工厂

    一个很长的问题 请耐心等待 我们正在使用 Spring JPA 来构建 Web 应用程序 我的团队正在争论注射问题EntityManagerFactory in the GenericDAO APPFUSE 提供的基于 Generics 的
  • 是否可以向凸起按钮添加自定义悬停颜色?

    在处理一个使用 Material UI 组件库的项目时 我收到了一个自定义按钮悬停颜色的请求 该颜色超出了 MUI 主题的正常约定 我在 凸起按钮 源代码中找到了这个相关的代码块 https github com callemall mat
  • Spark SQL 中的 INSERT IF NOT EXISTS ELSE UPDATE

    Spark SQL 中是否有执行 INSERT IF NOT EXISTS ELSE UPDATE 的规定 我有 Spark SQL 表 ABC 其中有一些记录 然后我有另一批记录 我想根据它们是否存在于该表中来插入 更新该表中 我可以在
  • Matplotlib imshow() 翻转 x 和 y 轴

    我在用着pyplot with matplotlib 我想将一些数据显示为图像 当我使用imshow 数据与我想要的查看方式翻转 我如何切换 x 轴和 y 轴imshow 或到numpy在我将其发送到之前的数组imshow 即我希望水平轴是
  • 如何在 Xcode 中的 CALayer 上方制作按钮或标签?

    在我的故事板中 我添加了一个按钮和一个标签 在我的 ViewController 中 我以编程方式定义了一个 CALayer 并将其作为子层添加到 ViewController 的视图中 当我测试应用程序时 子层位于按钮和标签上方 但我想将
  • 无法在 Fedora 上安装 GDB

    如何在 Fedora Linux 机器上下载并安装 GDB GNU 调试器 我尝试从 gnu 网站下载 7 1 包 但在安装过程中失败 configure然后make命令 请分享我可以获得相关信息的来源 Thanks 我发现这个教程可能对安
  • 如何实现一个具有一次读取 4 位节点的二进制 trie?

    我正在尝试找到一种方法inline某种意义上的二进制字典树 基本上 二进制 trie 为二进制数中的每个槽都有一个节点 在 0 上向左分支 在 1 上向右分支 您将如何构造它以便一次读取 4 位而不是 1 似乎每个 trie 节点中有 16
  • 记录 Xamarin 未处理(Android 未捕获)异常

    我想记录未处理的异常 但我看到关于是否以及如何可能实现的信息存在冲突 我了解 Xamarin 提出了AndroidEnvironment UnhandledExceptionRaiser or AppDomain CurrentDomain
  • 了解 Python ReportLab 中的表坐标系

    我无法理解坐标系ReportLab表格样式 根据他们的文档 每个命令的第一个元素是其标识符 第二个和第三个参数确定单元格 受负坐标影响的单元格的坐标 从 Python 索引中的限制值 坐标给出为 列 行 紧随其后 电子表格 A1 模型 但不
  • RabbitMQ 消息传递 - 初始化消费者

    我想使用 RabbitMQ 将对象的状态连续广播给可能正在侦听的任何消费者 我想对其进行设置 以便当消费者订阅时它将获取最后一个可用状态 这可能吗 使用自定义最后值缓存交换 例如https github com squaremo rabbi
  • 无法在 Mac OS 10.8 中从终端使用 svn 命令

    Team SVN 命令在终端中运行良好 我已经卸载并安装了最新版本的 svnclient 从那时起 我无法从我的 mac 终端访问 svn 命令 以下是我在终端中看到的错误消息 dyld 未加载库 opt local lib libssl
  • Clojure可以通过宏生成函数吗?

    我正在尝试通过宏生成 fn 但是我遇到了一个奇怪的问题 代码在这里 defmacro test2 lmk fn lmk2 println lmk lmk2 test2 12 13 gt Error defmacro test3 fn lmk
  • Cordova/PhoneGap 中的 Dropbox.js 身份验证

    我正在 Cordova PhoneGap 中编写一个应用程序 它尝试使用 Dropbox js 从 Dropbox 获取文件 Cordova 版本是 3 0 1 Dropbox js 版本是 0 10 0 我的 Javascript 在桌面
  • 有没有更好的方法使用Python的类型模块为复合类型创建类型别名? [复制]

    这个问题在这里已经有答案了 我有一个带有一个参数的函数 它应该采用int or a None作为论证 有多种方法可以为此类复合类型创建类型别名 test py import typing IntOrNone 1 typing TypeVar
  • popToRootViewControllerAnimated 无法正常工作

    我有一个导航应用程序 当发生某些错误时 我想将用户转回他们开始的视图 因此我在这些条件下执行以下代码 self navigationController popToRootViewControllerAnimated YES 当它执行时 根
  • MongoDB 中可以有多少个集合而不损失性能?

    我看到默认情况下 MongoDB 有 24 000 个可用集合 内存为 16MB ns文件 如果我将其增加到 2GB 最大值 我可以得到3 000 000数据库中的集合 性能会不会有大幅下降 根据文档 大量集合不会影响性能 几乎不会 拥有大
  • Android/Java - 日期差异天数

    我使用以下代码获取当前日期 格式为 12 31 1999 即 mm dd yyyy Textview txtViewData txtViewDate setText Today is android text format DateForm
  • 为什么 gcc 在 main 的开头推送 %rbx ?

    最新版本的 gcc 正在生成对我来说没有意义的程序集 我没有使用任何优化来编译代码 但是 即使没有优化 此代码的某些部分也没有意义 这是C源 include