linux c 输出到终端,C 语言的 printf 是如何实现输出到终端的

#include

int main() {

int a = 3;

int b = 5;

int c = 7;

printf("%d",(a + b) * c);

return 0;

}

把上面程序使用gcc编译之后,默认得到的文件名为a.out[vagrant@10 04]$ ldd a.out

linux-vdso.so.1 => (0x00007ffe6d5f8000)

libc.so.6 => /usr/lib64/libc.so.6 (0x00007f476d62d000)

/lib64/ld-linux-x86-64.so.2 (0x00007f476d9fa000)

ldd模拟运行一遍程序,在运行过程中做动态链接,从而得知这个可执行文件依赖于哪些共享库,每个共享库都在什么路径下,加载到进程地址空间的什么地址。也就是说我们使用gcc编译器编译的时候规定动态链接的是/usr/lib64/libc.so.6[vagrant@10 04]$ readelf -h /usr/lib64/libc.so.6

ELF 头:

Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00

Class: ELF64

Data: 2's complement, little endian

Version: 1 (current)

OS/ABI: UNIX - GNU

ABI Version: 0

Type: DYN (共享目标文件)

Machine: Advanced Micro Devices X86-64

Version: 0x1

入口点地址: 0x224e0

程序头起点: 64 (bytes into file)

Start of section headers: 2146808 (bytes into file)

标志: 0x0

本头的大小: 64 (字节)

程序头大小: 56 (字节)

Number of program headers: 10

节头大小: 64 (字节)

节头数量: 76

字符串表索引节头: 75

可以看到该共享库支持的操作系统(OS)是UNIX,应用程序二进制接口(ABI)是GNU。所以我们去看下gnu的printf的源码实现

找了个最老的版本,看了下,太复杂。。/*

* linux/lib/write.c

*

* (C) 1991 Linus Torvalds

*/

#define __LIBRARY__

#include

_syscall3(int,write,int,fd,const char *,buf,off_t,count)// 路径在 include/unistd.h

#define _syscall3(type,name,atype,a,btype,b,ctype,c) \

type name(atype a,btype b,ctype c) \

{ \

long __res; \

__asm__ volatile ("int $0x80" \

: "=a" (__res) \

: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \

if (__res>=0) \

return (type) __res; \

errno=-__res; \

return -1; \

}

1384.html

疑惑点

lib不是内核的代码吗,不应该在进入内核前中断么,怎么是先进入的内核然后才触发中断呢?

原来lib目录本身也有Makefile会生成一个静态库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值