- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有这个简短的 hello world 程序:
#include <stdio.h>
static const char* msg = "Hello world";
int main(){
printf("%s\n", msg);
return 0;
}
我用gcc编译成如下汇编代码:
.file "hello_world.c"
.section .rodata
.LC0:
.string "Hello world"
.data
.align 4
.type msg, @object
.size msg, 4
msg:
.long .LC0
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
movl msg, %eax
movl %eax, (%esp)
call puts
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
我的问题是:如果我用汇编编写这个程序(而不是用 C 编写然后编译成汇编),那么这段代码的所有部分都是必要的吗?我理解码装说明,但有些部分我不理解。例如,我不知道 .cfi* 是什么,我想知道是否需要包含它才能用汇编语言编写这个程序。
最佳答案
在这个平台上工作的绝对最低限度是
.globl main
main:
pushl $.LC0
call puts
addl $4, %esp
xorl %eax, %eax
ret
.LC0:
.string "Hello world"
但这打破了一些ABI要求。符合 ABI 的程序的最低要求是
.globl main
.type main, @function
main:
subl $24, %esp
pushl $.LC0
call puts
xorl %eax, %eax
addl $28, %esp
ret
.size main, .-main
.section .rodata
.LC0:
.string "Hello world"
目标文件中的所有其他内容要么是编译器没有尽可能紧密地优化代码,要么是要写入目标文件的可选注释。
.cfi_*
指令尤其是可选注释。当且仅当抛出 C++ 异常时函数可能在调用堆栈上时,它们是必需的,但它们在您可能想要从中提取的任何程序中有用堆栈跟踪。如果你打算用汇编语言手工编写重要的代码,那么学习如何编写它们可能是值得的。不幸的是,它们的记录非常少;我目前没有找到任何我认为值得链接的内容。
线
.section .note.GNU-stack,"",@progbits
了解您是否正在手工编写汇编语言也很重要;它是另一个可选注释,但很有值(value),因为它的意思是“此目标文件中的任何内容都不需要堆栈是可执行的”。如果一个程序中的所有目标文件都有这个注解,内核将不会使堆栈可执行,从而稍微提高安全性。
(为了表明您确实需要堆栈是可执行的,您放置“x”
而不是“”
。GCC可能会做如果您使用它的“嵌套函数”扩展名,请这样做。(不要那样做。))
可能值得一提的是,在 GCC 和 GNU binutils(默认情况下)使用的“AT&T”汇编语法中,存在三种行:上面有一个标记,以冒号结尾,是一个标签。 (我不记得什么字符可以出现在标签中的规则。)第一个标记以点开头,不以冒号结尾的行是对汇编程序的某种指令。其他任何内容都是汇编指令。
关于c - 如果我要用汇编编写程序,这个 HelloWorld 汇编代码的哪些部分是必不可少的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39550402/
这个问题已经有答案了: What does "Could not find or load main class" mean? (63 个回答) 已关闭 7 年前。 我用java语言编写了一个简单的程
在使用 Expo 的 React Native 项目中,我尝试使用 export 部署以下云函数: 注意:我在 index.js 中使用 Javascript。 export const helloW
解决了“无法找到或加载主类Hello”错误的问题后...运行程序后我再次遇到这个问题(我使用文本板)代码是: class HelloWorld { public static void m
我最初尝试像这样推送我的(有史以来第一次!)git repo: $ git push helloworld 但我得到了这个: To git-smichaels@free5.projectlocker.
全新安装,通过 vue cli 安装 Vue。运行 vue create app并使用基本配置进行设置。 从 Home.vue 中删除 HelloWorld.vue 组件和附带的导入代码。 运行 np
我第一次编程有点问题。我收到消息 可以获取“c:\users\amittler\source\repos\HelloWorld...”吗? 谢谢你的帮助 最佳答案 是的,得到这个就可以了。 您的 ID
好的,我只是无法让 java 运行我的 .class 文件:我按照 Oracle tutorial 中的步骤操作并尝试运行这个程序: class HelloWorldApp { public
我是 Scala 和 SBT 的新手,所以我可能会遗漏一些明显的东西。 我试图在 http://www.scalafx.org/docs/quickstart/ 上编译 HelloWorld 示例 我
这是我的设置: docker pull riot/riotbuild wget https://github.com/RIOT-OS/RIOT/archive/2019.04.zip unzip 20
我一直在尝试创建我的第一个 Jenkins 插件。一切都很好,只是全局配置在 jenkins 服务重新启动后不会保留。 只要服务不重新启动,配置就可以很好地保存。 全局配置果冻文件... Jenki
我尝试从终端运行基本的 HelloWorld.class 文件。 我使用以下输入: Java HelloWorld.class 但它说: Error: Could not find or load "
以下代码取自 http://doc.akka.io/docs/akka/2.2.3/AkkaScala.pdf import akka.actor.Actor object Greeter { c
我带着这样一个微不足道的问题来到 Stack Exchange 感到内疚,但我整个上午都在为它苦苦思索,似乎无处可去。我正在尝试运行 Grails 教程中的简单 HelloWorld 应用程序:htt
好吧,这真的让我很生气。我在我的模拟器和安卓设备上都运行了它。该代码不显示“Helloworld, Android -mykong.com”。我启动应用程序,在模拟器上找到它,单击它,它会转到应用程序
我回到了 c++(我已经好几年没用过它了)来学习 box2d API。 我确切地说我在 Linux 系统 (Ubuntu) 上并且我已经从 this guide 之后的源代码安装了 box2d(2.3
社区成员推荐我分析以下内容,以了解 ARM 架构中发出的系统调用。我怀疑如何在这种结构中获取程序。我已经尝试过 gdb disas 命令,但部分不可见。请帮助。 .data HelloWorldStr
在编译我的 wxWidget HelloWorld 应用程序时,出现以下错误: Warning 1 warning LNK4098: defaultlib 'LIBCMTD' conflicts
我刚刚为我的 eclipse 安装了 c/c++ 开发工具,一切正常,除了当我运行 hello world 程序时控制台中没有打印任何文本,但我没有收到任何错误。我真的很困惑,有人知道这是为什么吗?
我在以下文件夹 C:\Program Files\Java 中安装了 Java 1.7.0。我的操作系统是带有 Service Pack 3 的 Windows XP(2002 版)。 我设置的环境变
前言 讲解Spring之前,我们首先梳理下Spring有哪些知识点可以进行入手源码分析,比如: Spring IOC依赖注入 Spring AOP切面编程 Spri
我是一名优秀的程序员,十分优秀!