C++书写”c++编写hello worldWorld“受阻,求助


萌萌松
CSDN认证博客专家
CSDN认证企业博客
分类专栏
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
成就一亿技术人!
hope_wisdom 发出的红包
实付元使用余额支付
点击重新获取
钱包余额
0
抵扣说明: 1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。余额充值
你应该不会以为main函数是程序执行的第一行代码吧?你应该也不会以为main函数是程序的唯一入口吧?今天我们通过示例演示如何写出没有main函数的极简的HelloWorld程序。从hello world程序说起用C语言编写一个hello world程序是非常简单的是,示例代码如下:#include <stdio.h>
char str[] = "Hello world!\n";
int main() {
printf("%s", str);
}
我们都知道C/C++程序可分为动态链接和静态链接两种,对应的上述程序可以编译成动两个版本:gcc main.c -o main_dynamic # 动态链接
gcc -static main.c -o main_static # 静态链接虽然编译出来的程序执行结果是一样的,但main_dynamic和main_static的大小相差很多,一个是17KB,另一个是891KB,相差了52倍!再深入看二者可执行文件的内容,发现无论是代码段、数据段、还有未初始化数据段相差都很大。令人不解的是上述hello world程序只有6行代码,为何生成的二进制代码段却如此之长?更令人发指的是静态链接产生的二进制代码竟然有678KB!很显然这是因为程序中除了打印Hello World还夹带了很多“私货”,感兴趣的话可以通过objdump -d main_static查看反编译的汇编代码,会刷屏。有没有什么办法减小程序体积呢?一个最小的hello world程序我们通过C语言内嵌汇编的方法,编写一个体积更小的Hello World程序。代码不调用任何libc的库函数,而是通过使用汇编指令直接使用Linux系统调用来完成输出。// no_main.c
char str[] = "Hello world!\n";
void my_print() {
asm( "movl $13,%%edx \n\t"
"movq %0,%%rcx \n\t"
"movl $0,%%ebx \n\t"
"movl $4,%%eax \n\t"
"int $0x80 \n\t"
::"r"(str):"edx", "rcx", "ebx");
}
void my_exit() {
asm( "movl $0,%ebx \n\t"
"movl $1,%eax \n\t"
"int $0x80 \n\t");
}
void my_entry_point() {
my_print();
my_exit();
}上述代码有说明如下:代码中使用了汇编调用Linux系统调用,调用号4是sys_write,即向一个文件描述符输出内容。代码使用1号系统调用sys_exit完成程序退出,这个必须要有,因为代码段是逐行执行的,如果没有退出指令则程序会一直往下执行而出现非法访问。代码中没有main函数,而是使用了my_entry_point()作为程序入口。这当然是允许的,只要在连接的时候通过ld -e指定程序入口即可。程序的编译命令如下:gcc -c no_main.c -o no_main.o # 编译成目标文件
ld -static -e my_entry_point -o no_main no_main.o # 对目标文件进行链接,同时指定自定义的Entry Point关于编译的四个步骤,可参考C/C++程序编译过程为什么要分为四个步骤?编译出的结果绝对是极简性冷淡风,非常的小巧,代码段只有203字节,而数据段只有14字节(就是"Hello world!\n"字符串的长度),当然他是能正常工作的!总结本文使用C内嵌汇编的方式编写出了一个没有main函数的HelloWorld程序。思考:main函数之前和之后分别做了什么?参考C/C++程序编译过程为什么要分为四个步骤?《程序员的自我修养——链接、装载与库》

我要回帖

更多关于 c++编写hello world 的文章

 

随机推荐