system programming and API and ABI

系统编程、API及ABI

clip_image001

系统编程

Linux系统编程中有三大基石:系统调用、C库和C编译器

clip_image003 clip_image005  clip_image007

系统调用

       系统编程始于系统调用,系统调用syscalls是为了从操作系统获得服务或者资源而从用户空间向内核发起的函数调用。比如我们比较熟悉的readwrite函数。

       操作系统的主要功能是为应用程序的运行创建良好的环境,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。

clip_image008

C

clip_image009

ClibcUnix应用程序的核心。就算你使用别的语言,c库也常常扮演着非常重要的角色,它常被高级的库封装,提供核心服务或者方便的系统调用。

glibclinux系统中最底层的api,几乎其它任何运行库都会依赖于glibcglibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万有。而就像其他的 UNIX 系统一样,其内含的档案群分散于系统的树状目录结构中,像一个支架一般撑起整个作业系统。在 GNU/Linux 系统中,其C函式库发展史点出了GNU/Linux 演进的几个重要里程碑,用 glibc 作为系统的C函式库,是GNU/Linux演进的一个重要里程碑。

C编译器

clip_image010

       Linux中,标准的C编辑器是GNU编辑器工具集gcc

       GCCGNU Compiler CollectionGNU编译器集合)是一套由GNU工程开发的支持多种编程语言的编译器。GCC是自由软件发展过程中的著名例子,由自由软件基金会以GPL协议发布。GCC是大多数类Unix操作系统(如LinuxBSDMac OS X等)的标准的编译器,GCC同样适用于微软的WindowsGCC支持多种计算机体系芯片,如x86ARM,并已移植到其他多种硬件平台。GCC原名为GNU C编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,并支持处理C++。后来又扩展能够支持更多编程语言,如FortranPascalObjective-CJavaAdaGo等。

API以及ABI

在系统级别上,影响可移植性的因素主要包括两个互相独立的定义和描述集合,一个是应用程序接口API,另一个是应用程序二进制接口ABI。两个都定义和描述了软件不同模块间的接口。

API

clip_image012

APIApplication Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

ABI

clip_image013

应用程序二进制接口(application binary interfaceABI 描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口 ABI不同于API API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译 ,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。 ABI掩盖了各种细节,例如:调用约定控制着函数的参数如何传送以及如何接受返回值;系统调用的编码和一个应用如何向操作系统进行系统调用;以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库等等。一个完整的ABI,像 Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The difference between library functions and system calls

库函数和系统调用的区别

       库函数是更高级别的,完全在用户空间里运行,并为程序员提供了更方便的做实际工作的函数接口。Higher levelrun in user spacemore convenient

       系统调用代表用户以内核模式工作,由操作系统本身的内核提供。In kernel mode

       库函数printf看上去类似于一般输出函数,但是它实际上只是格式化你提供给字符串的数据,并用低级系统调用write编写字符串数据,然后将数据发送到一个与终端的标准输出关联的文件中。