系统编程是什么(转)

部分摘自《Linux System Programming 》作者: Robert Love
刘建文略译(http://blog.csdn.net/keminlau

System Programming

过去的Unix编程是没有系统不系统之分的。

即便是开发 X Window也是在系统级(system-level)编程,看到系统的全部API。现代的操作系统编程有所谓[系统级编程],使用与[应用编程]不同的API(System programming API) 。

从编程的形式和耗费心力上。系统编程与应用编程没有本质差别,这也意味着一个经验丰富的应用程序猿转向系统编程难度不大。

系统编程与应用编程的不同在于:

  • 第一,系统编程更接近硬件。系统程序猿必须熟悉硬件环境和操作系统环境;相对的,应用程序猿很多其它是熟悉应用的环境;
  • 第二,系统编程使用的函数库和库函数调用方法与应用编程有一些不同。比方,在调用系统调用(syscall)时使用所谓的陷入方式,也就是软中断方式。
    近年来,随计算应用深化,应用编程有远离系统编程的趋向。

只是,这并不能说或者预言系统编程的末日的到来。由于,有人用Javascript或C#写应用就要有人写它的解释器和执行时。

此外,操作系统代码仅仅能使用系统级编程。


本书的一些核心问题:

系统级接口(system-level interface)究竟是什么?又怎样编写Linux的系统级应用?
内核和C库详细提供了什么给我们?
怎样编写优质代码?Linux又有什么已知的陷阱(tricks )?
Linux的系统调用是怎样实现的?
What neat system calls are provided in Linux compared to other Unix variants?
How does it all work? Those questions are at the center of this book.

Linux系统编程须要熟悉三大块内容:系统调用、C库和C编译器。

System Calls

[系统调用]就是用户空间与内核之间的函数接口,目的是为了给用户空间的程序请求内核服务和资源。与其他非常多操作系统相比。Linux实现的系统调用少非常多。比方,Linux为I386体系实现了300个左右的系统调用。而 Microsoft Windows据说实现数以千计的系统调用。

Linux内核的不同平台实如今系统调用上存在差异,只是90%的系统调用是同样的。

Invoking system calls

出于安全性等因素,应用代码是不可以直接调用系统调用的。必须使用特殊的[陷入](trap)机制。一种“知会”内核进行工作的函数调用形式(KEMIN:证明两“系统”的耦合度较弱,比直接调用方式要弱。以系统论的角度考究syscall也非常有意思)。陷入机制的详细实现也是因不同的体系而有所不同的。

比方I386体系,应用代码通过触发软中断指令(int 0x80)来调用syscall。那0x80是什么呢?软件中断向量号吗?回答否。

应用代码必须通过处理器的寄存器向告诉内核向量号和调用參数。比方。假设应用代码调用open(),它得置eax值5,然后把參数放在另外的五个寄存器:ebx, ecx, edx, esi, 和edi(所以系统调用至多使用五个參数),这些寄存器保存实用户空间的地址,也就是參数数据所在。

作为一位系统程序猿,你一般不需干涉系统调用的过程,由于调用过程由体系定义。而且由C库和C编译器自己主动处理。

The C Library

C库是全部UINX应用的核心。由于不管你使用什么语言,你的代码终于还是调用C库。其他高级语言的库都是基于C库构建的,或者说是这些库是对C库的包装。

如今的Linux,使用的C库是GNU libc。行话glibc。

glibc不不过个程序语言库,比方C标准库。它还是一个系统库,并且是一个现代操作系统库,函数涵盖了对系统调用的包装、线程支持、网络支持等。

The C Compiler

Linux的C编译器是gcc,过去gcc代表GNU C Compiler,是cc的在GNU项目的实现;如今gcc代表GNU Compiler Collection,只是gcc 仍然是C编译器的入口。

Unix系统(包含Linux)使用的编译器与系统编程是高度相关的。由于编译器负责实现了C标准和系统ABI。

APIs and ABIs

无人不希望自己写的程序具有非常好的移植性(portability)。能够执行在不同软件平台(如操作系统或应用框架)、硬件平台(如处理器体系及载板),甚至跨平台的开发版本号执行。

有多种因素影响着程序的可移植性。其中就有两组不同的[系统接口]影响程序的可移植性:第一组是应用编程接口(API),还有一组是应用二进制接口(ABI)。

APIs

API是两支软件在源码级的接口。通过这个标准的接口(一般以函数形式实现),客户代码(一般称高级别的软件代码)能够调用服务代码(低级别的软件代码)。API本身是抽象的,它仅定义了一个接口,不涉入应用程序怎样实现的细节。

系统论里的接口范畴

接口或者port是两子系统边界[信息交换]的规格或约定方式,用通俗的理解就是。信息是什么样的。接口是信息的格式。

应用编程接口。就是软件系统不同组成部分衔接的约定。

程序设计的实践中,编程接口的设计首先要使系统的职责得到合理划分。良好的接口设计能够减少系统各部分的相互依赖。提高组成单元的内聚性,减少组成单元间的耦合程度,从而提高系统的维护性和扩展性。

因为API是抽象的,必须清晰差别接口定义与接口的实现。比方[C标准库]是API,uclibc是一个实现;POSIX 是API,glibc是一个实现。

那么API一般涵盖什么样的函数呢? 这是一个非常有意思的问题。比方C标准库是一种语言库,它必须非常通用。所以接口函数不能依赖软件或硬件特性;相反POSIX 是操作系统标准,它相对没那么的通用。

ABIs

API是源码级别接口,是逻辑约定;而ABI是二进制级别接口,定义的在特定的架构上两个软件模块之间的接口的物理实现方式。这样的[物理实现约定]保证二进制代码兼容,也就是保证一段目标代码可以在不论什么具有相同ABI的系统上都正常运作,不须要又一次编译源码。

ABI([物理实现约定]) 的内容包含调用约定(calling conventions)、字节序(byte ordering)、寄存器使用(register use)、系统调用实现方式、对象链接、库行为和二进制格式。以调用规则为例,它规定了函数怎样被调用。參数怎样传递,哪些寄存器被保留和哪些会被破坏,以及调用者怎样提取返回的结果。

虽然以前尝试着为特定架构下不同的操作系统(特别是i386上的Unix操作系统)定义唯一的ABI,然而到眼下为止还没有取得成效。相反,包含Linux在内的操作系统都尝试定义各自独立的ABI,这些ABI和架构紧密相连。

大部分的ABI涉及了机器级别的概念,如特定的寄存器或者汇编指令。

因此。在Linux系统中。每个机器架构都有自己的ABI集合,其实,我们以机器架构的名称来称呼这些ABI,比如alpha x86-64等。

1.4 Linux编程概念、POSIX和系统库

全部的Unix系统,包含Linux系统。都提供了一个共同的抽象和接口集合,这个共同点定义了Unix。

如对文件和进程的抽象、管道和套接字管理的接口等等,都是Unix的核心内容。

综上,个人理解,系统编程与应用编程的不同在于:调用的接口不同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值