C语言中没有main函数生成可执行程序的几种方法
#define begin main
int begin(void)
{
printf(
"Hello, World!\n");
return
;
}
#include <stdio.h>
#define begin m##a##i##n
int begin(void)
{
printf(
"Hello, World!\n");
return
;
}
严格来说,这种方式只算是一种技巧......
2、_start函数
_start函数是C程序的入口函数,会调用main函数。在调用main函数之前,会先执行_start函数分配必要的资源,然后再调用main函数。但是在用gcc编译程序时可以使用-nostartfiles选项来重写_start函数。示例程序如下:
#include <stdlib.h>
_start(void) {
printf(
"Hello, World!\n");
exit(
);
}
-nostartfiles _start.c
-o a.out
: file format elf64
-x86
-
Disassembly of section .plt
:
<puts@plt
-0x10
>
:
: ff
ea
00 pushq 0x2001ea(
%rip)
# 600510 <_GLOBAL_OFFSET_TABLE_+0x8>
: ff
ec
00 jmpq
*0x2001ec(
%rip)
# 600518 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c
: 0f
1f
00 nopl 0x0(
%rax)
<puts@plt
>
:
: ff
ea
00 jmpq
*0x2001ea(
%rip)
# 600520 <_GLOBAL_OFFSET_TABLE_+0x18>
:
00 00 00 00 pushq $0x0
40033b
: e9 e0 ff ff ff jmpq
<puts@plt
-0x10
>
<
exit@plt
>
:
: ff
e2
00 jmpq
*0x2001e2(
%rip)
# 600528 <_GLOBAL_OFFSET_TABLE_+0x20>
:
00 00 00 pushq $0x1
40034b
: e9 d0 ff ff ff jmpq
<puts@plt
-0x10
>
Disassembly of section .text
:
<_start
>
:
:
push
%rbp
:
e5 mov
%rsp,
%rbp
: bf
00 mov $0x400368,
%edi
: e8 d2 ff ff ff callq
<puts@plt
>
40035e
: bf 00 00 00 00 mov $0x0,
%edi
: e8 d8 ff ff ff callq
exit@plt
#include <stdlib.h>
int nomain(int i, int j, int k) {
printf(
"Hello, World!\n");
exit(
);
}
-nostartfiles
-e nomain m.c
-o a.out
: file format elf64
-x86
-
Disassembly of section .plt
:
<puts@plt
-0x10
>
:
: ff
f2
00 pushq 0x2001f2(
%rip)
# 600518 <_GLOBAL_OFFSET_TABLE_+0x8>
: ff
f4
00 jmpq
*0x2001f4(
%rip)
# 600520 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c
: 0f
1f
00 nopl 0x0(
%rax)
<puts@plt
>
:
: ff
f2
00 jmpq
*0x2001f2(
%rip)
# 600528 <_GLOBAL_OFFSET_TABLE_+0x18>
:
00 00 00 00 pushq $0x0
40033b
: e9 e0 ff ff ff jmpq
<puts@plt
-0x10
>
<
exit@plt
>
:
: ff
ea
00 jmpq
*0x2001ea(
%rip)
# 600530 <_GLOBAL_OFFSET_TABLE_+0x20>
:
00 00 00 pushq $0x1
40034b
: e9 d0 ff ff ff jmpq
<puts@plt
-0x10
>
Disassembly of section .text
:
<nomain
>
:
:
push
%rbp
:
e5 mov
%rsp,
%rbp
:
ec
sub $0x10,
%rsp
:
7d fc mov
%edi,
-0x4(
%rbp)
40035b
:
f8 mov
%esi,
-0x8(
%rbp)
40035e
:
f4 mov
%edx,
-0xc(
%rbp)
: bf
00 mov $0x400375,
%edi
: e8 c5 ff ff ff callq
<puts@plt
>
40036b
: bf 00 00 00 00 mov $0x0,
%edi
: e8 cb ff ff ff callq
<
exit@plt
>
#include <stdlib.h>
void func() {
printf(
"I am func....\n");
}
int nomain1(int i, int j, int k) {
func();
printf(
"%s: Hello, World!\n", __func__);
exit(
);
}
~]
# gcc -nostartfiles p.c
/usr
/bin
/ld
: warning
: cannot find entry symbol _start; defaulting to
在单独使用nostartfiles选项时会报警告,生成的可执行程序可以执行,但是会产生段错误,去掉对func()函数的调用就不会产生段错误了。将生成的可执行程序反汇编,和使用前面的方法生成可执行程序的反汇编结果比较,发现除了函数名不一样外,没有其他区别,不知道为什么会产生段错误。知道的麻烦告知一声,拜谢!
C语言中没有main函数生成可执行程序的几种方法的更多相关文章
- C语言中存储多个字符串的两种方式
C语言中存储多个字符串的两种方式 方式一 二维字符串数组 声明: char name[][] = { "Justinian", "Momo", " ...
- 20155212 C语言实现linux下pwd命令的两种方法
20155212 C语言实现linux下pwd命令的两种方法 学习pwd命令 通过man pwd命令查看 pwd [OPTION],一般不加参数 -P显示当前目录的物理路径 -L显示当前目录的连接路径 ...
- Java中取小数点后两位(四种方法)
摘自http://irobot.iteye.com/blog/285537 Java中取小数点后两位(四种方法) 一 Long是长整型,怎么有小数,是double吧 java.text.D ...
- linux中删除文件内空白行的几种方法。
linux中删除文件内空白行的几种方法 有时你可能需要在 Linux 中删除某个文件中的空行.如果是的,你可以使用下面方法中的其中一个.有很多方法可以做到,但我在这里只是列举一些简单的方法. 你可能已 ...
- (转载)Java中如何遍历Map对象的4种方法
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- linux中快速清空文件内容的几种方法
这篇文章主要介绍了linux中快速清空文件内容的几种方法,需要的朋友可以参考下 $ : > filename $ > filename $ echo "" > f ...
- (转)在网页中JS函数自动执行常用三种方法
原文:http://blog.sina.com.cn/s/blog_6f6b4c3c0100nxx8.html 在网页中JS函数自动执行常用三种方法 在网页中JS函数自动执行常用三种方法 在HTML中 ...
- Java 获取*.properties配置文件中的内容 ,常见的两种方法
import java.io.InputStream; import java.util.Enumeration; import java.util.List; import java.util.Pr ...
随机推荐
- Objective-c 数组对象
首先我们必须知道数组的概念:数组是有序的对象集合,一般情况下,一个数组的对象都是相同类型的.数组当中也存在可变数组和不可变数组. 1. 不可变数组 (NSArray) 可变数组 NSMutable 是 ...
- 一道试题引发的血案 int *ptr2=(int *)((int)a+1);
某日,看到一道比较恶心的C语言的试题,考了很多比较绕的知识点,嘴脸如下: int main(void) { int a[4] = {1, 2, 3, 4}; int *ptr1=(int *)(&am ...
- Lucence.net索引技术 二
一. Lucene索引创建和优化 [版本2.9.0以上] Lucene索引的创建首先需要取得几个必须的对象: 1.分词器//可以采用其他的中文分词器 StandardAnalyzer analyzer ...
- ASP.NET MVC Framework
ASP.NET MVC Framework是微软在ASP.NET中所添加的一组类库,这组类库可以使用Model-View-Controller的设计模式来开发ASP.NET的应用程序.它与现有的ASP ...
- Servlet运行过程详解
比如,在浏览器地址栏输入http://ip:port/web01/hello step1,浏览器依据ip,port建立与servlet容器(容器同时也是一个简单的web服务器)之间的连接. step2 ...
- 03-C语言编码规范和变量
目录: 一.C语言的编码规范 二.变量 三.浮点型float 四.变量名命名规则 五.变量作用域与生命周期 回到顶部 一.C语言的编程规范 1 语句可以分开放在任意位置 2 空格可以让代码更清晰 3 ...
- 02-C语言执行过程
目录: 一.MACOS系统操作 二.C语言的使用方式 三.编码 四.编译 五.运行 六.分析第一个C程序 七.预处理指令#include 八.完整执行过程 回到顶部 一.MACOS系统操作 操作计算机 ...
- 基于FPGA的信号消抖
上一篇写了一个按键消抖,按键消抖需要一个计数器.可是有些信号是不需要这么负责的,仅仅是抖动而已.于是我在上一篇博文的基础上做了一点修改,于是有了这个信号消抖的程序 module sig_nojitte ...
- android 自定义百度地图放大缩小
自定义实现Android百度地图的缩放图标,需要自定义一个缩放控件,实现效果如下: 这里的缩放效果,实现了点击按钮可以对地图的放大缩小,通过手势放大与缩小也控制缩放图标的可用状态.具体实现如下: zo ...
- 统计难题(trie树)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...