C专家编程-Chapter6 运行时数据结构(转)
a.out是链接器的输出。
a.out is a file format used in older versions of Unix-like computer operating systems for executables, object code, and, in later systems, shared libraries. The name stands for assembler output.
a.out remains the default output file name for executables created by certain compilers/linkers when no output name is specified, even though these executables are no longer in the a.out format.
———————————————————————————————————————————————
目标文件和可执行文件有若干种不同的格式。绝大多数SVR4实现中都采用了一种称作ELF(Executable and linking Format)的格式。其它BSD UNIX等还有别的格式。但所有这些不同格式具有一个共同的概念,段(segment)。
段是二进制文件中简单的区域,里面保存了和某种特定类型(如符号表条目)相关的所有信息。一个段一般包含几个section。
不要把Unix中的段的概念跟Intel x86架构中段的概念混淆。
在Unix中,段表示一个二进制文件相关的内容块。
在Intel x86的内存模型中,段表示一种设计的结果。在这种设计中,地址空间并非一个整体,而是分成一些64K大小的区域,称之为段。
检查可执行文件的内容的另一种方法是使用nm或dump实用工具。在a.out上运行nm工具。nm -sx a.out。在一个可执行文件上执行size命令时,他会告诉你这个文件中的三个段text,data,bss的大小,如size a.out。各个段的意义参见。
如以下程序运行nm命令:
#include <stdlib.h>
char pear[40];
static double peach;
int mango = 13;
static long melon = 2001;
int
main(void){
int i = 3, j, *ip;
ip = malloc(sizeof(i));
pear[5] = i;
peach = 2.0 * mango;
return 1;
}
结果是:
Type Bind Segment Name
OBJT LOCL .bss peach
OBJT GLOB .bss pear
OBJT GLOB .data mango
OBJT LOCL .data melon
FUNC GLOB .text main
FUNC GLOB UNDEF malloc
……
数据段保存在目标文件中。
BSS段不保存在目标文件中。(除了记录BSS段在运行时所需要的大小)
文本段是最容易受优化措施影响的段。
a.out文件的大小受调试状态下编译的影响,但段不受影响。
———————————————————————————————————————————————
C语言自动提供的服务之一是跟踪调用链,那些函数调用了那些函数,当下一个return语句执行后,控制将返回何处等。解决这个问题的经典机制是堆栈中的过程活动记录。过程活动记录是一种数据结构,如下:
局部变量,参数,静态链接(C语言中不使用),指向先前结构的指针,返回地址。
系统尽可能的把过程活动记录的内容放到寄存器中,是函数调用的速度更快。担当函数调用链非常深,寄存器窗口不够用时,寄存器的内容就会被保存到堆栈中保留的活动记录空间中,以便重新利用这些寄存器。
———————————————————————————————————————————————
控制线程
setjmp()和longjmp()是通过上述过程活动记录实现的。goto只能在函数内跳动,而它们可以到函数外。
setjmp保存了程序的计数器和当前的栈顶指针,可能还有一些初始值。longjmp恢复这些值,有效地转移控制并把状态重置回保存状态的时候。
这对函数最大的用途是错误恢复。只要还没有从函数中返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从那里重新开始。相当于C++中的catch和throw。
使用例子:
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
void banana(){
printf("in banana()\n");
longjmp(buf, 1);
printf("you'll never see this");
return;
}
int
main(void){
if(setjmp(buf))
printf("back in main\n");
else{
printf("first time through\n");
banana();
}
return 0;
}
输出:
debian:/home/banyan# ./jmp
first time through
in banana()
back in main
———————————————————————————————————————————————
一些有用的C语言工具:
indent 美化格式,缩进等。
cflow 打印程序中调用者/被调用者关系
dump -Lv 打印动态链接的信息
ldd 打印文件所需的动态库
file 告诉你一个文件包含的内容(如可执行文件、数据、ASCII,shell,script,archive等)
time 显示程序所使用的实际时间和CPU时间。
———————————————————————————————————————————————
附:什么是SVR4?我们为什么要选择SVR4?zz
SVR4是UNIX操作系统的一种新的内核标准,是迄今为止内核版本最新的UNIX
SVR4并不代表一个具体的UNIX变体,而只是一个内核的标准。SVR4有极高的标准性,那意味着你学好了SVR4可以在所有SVR4内核的操作系统上进行统一的操作(不会产生学习了一个UNIX系统还要学习另外的困惑)
SVR4(UNIX System V Release4)是AT&T在1989年首次发行的;SVR4集成SVR3,4BSD,SunOS,以及XENIX的一些特性,还添加了一些新 功能,如实时调度,Korn shell,以及对STREAMS子系统的改进;SVR4是迄今为止最新的UNIX
SVR4的优点如下
1、标准性
符合SVID(AT&T的System V接口定义)、IEEE POSIX规范,以及X/OPEN财团的X/OPEN可移植导引。应该说AT&T公司出品的SVR4是UNIX味儿最浓的UNIX。现在流行的现 代UNIX大多都是基于SVR4的。
2、先进性
AT&T UNIX System V Release4 是迄今为止内核版本最新的UNIX。在这之后USL发行了UNIX SVR4.2,此后又有新的SVR4的发行,其中最新的是SVR4.2/ES/MP。它在SVR4.2的基础上加入了安全性和多处理器的支持,并支持轻量 级进程。(这就是unixware2.1采用的内核)
SVR4.2支持内模块的动态加载(在系统运行中,内核是可以动态变化的)这意味着改变内核而不需要重新启动计算机。
另外,SVR4提供了新的图形用户界面(GUI) -- Motif和sun的openlook(openwindow)。
SVR4.2还增加了对PC新硬件的支持。
3、友好的用户界面
广大的操作系统爱好者往往喜欢从界面的友好性来评价操作系统。
对于字符终端用户SVR4提供的是face界面(OAM)。它将常用的系统管理(如添加新用户、备份…)图形化了。还提供了在线帮助(类似于ScoAdmin)
对于图形终端用户,SVR4提供了openlook标准图形界面。
4、改进的VM(虚拟内存)结构
SVR4的内存管理不再基于原SVR3中“区”的结构,而采用请求分页技术。SVR4采用双表针时钟的页面置换策略,这样的改进降低了页面失效率。
5、改进的进程管理
SVR4支持内核线程、用户线程和轻量级进程。SVR4提供了一组系统调用,它是SVR3和BSD信号功能的超集。同时也支持老的不可靠的信号。
SVR4在进程调度方面做了很多改进,包括:
1)支持要求实时响应的多种应用程序。
2)把调度策略同实现它的机制相分离。
3)应用程序能够控制它的优先级和调度。
4)定义了一个对内核有良好定义接口的调度框架。
5)允许新的调度策略以模块方式加入,包括调度器动态加载的实现。
6)限制临界时间性应用程序的调度延迟。
在进程通信方面SVR4使用流(STREAMS)作为它的基本框架来实现管道(pipes)和有名管道(FIFO)。SVR4的管道是双向的,可同时进行读写操作。
在同步方面,加入了多处理机支持。并用自旋锁代替了信号灯。
6、高级文件系统支持
SVR4除了支持SystemV传统的文件系统s5fs之外,还加入了ufs和vxfs。
Ufs是伯克利快速文件系统,建立在s5fs的基础之上,增加了硬盘的访问速度,并节省了硬盘空间。这种文件系统支持长文件名(大于14个字符)、符号连 接和原子命名。并支持片段(slice)就是对磁盘块的进一步划分,用mkfs命令创建文件系统时可以指定slice的大小。一般为1,2,4或8。
Vxfs是Veritas高级文件系统。它是一种日志文件系统,同时提供了许多先进的功能。如系统崩溃的快速恢复、磁盘配额等等
7、设备管理的改进
SVR4支持内核模块的动态加载,具有新的设备驱动程序。内核对驱动程序是透明的,大大简化了驱动程序编写的复杂性。
如果您是一位SVR4的爱好者与支持者,您就应该选择SVR4的UNIX操作系统,如SUN 的 Solaris,IBM的AIX,SCO 的 Unixware等等。
a.out is a file format used in older versions of Unix-like computer operating systems for executables, object code, and, in later systems, shared libraries. The name stands for assembler output.
a.out remains the default output file name for executables created by certain compilers/linkers when no output name is specified, even though these executables are no longer in the a.out format.
———————————————————————————————————————————————
目标文件和可执行文件有若干种不同的格式。绝大多数SVR4实现中都采用了一种称作ELF(Executable and linking Format)的格式。其它BSD UNIX等还有别的格式。但所有这些不同格式具有一个共同的概念,段(segment)。
段是二进制文件中简单的区域,里面保存了和某种特定类型(如符号表条目)相关的所有信息。一个段一般包含几个section。
不要把Unix中的段的概念跟Intel x86架构中段的概念混淆。
在Unix中,段表示一个二进制文件相关的内容块。
在Intel x86的内存模型中,段表示一种设计的结果。在这种设计中,地址空间并非一个整体,而是分成一些64K大小的区域,称之为段。
检查可执行文件的内容的另一种方法是使用nm或dump实用工具。在a.out上运行nm工具。nm -sx a.out。在一个可执行文件上执行size命令时,他会告诉你这个文件中的三个段text,data,bss的大小,如size a.out。各个段的意义参见。
如以下程序运行nm命令:
#include <stdlib.h>
char pear[40];
static double peach;
int mango = 13;
static long melon = 2001;
int
main(void){
int i = 3, j, *ip;
ip = malloc(sizeof(i));
pear[5] = i;
peach = 2.0 * mango;
return 1;
}
结果是:
Type Bind Segment Name
OBJT LOCL .bss peach
OBJT GLOB .bss pear
OBJT GLOB .data mango
OBJT LOCL .data melon
FUNC GLOB .text main
FUNC GLOB UNDEF malloc
……
数据段保存在目标文件中。
BSS段不保存在目标文件中。(除了记录BSS段在运行时所需要的大小)
文本段是最容易受优化措施影响的段。
a.out文件的大小受调试状态下编译的影响,但段不受影响。
———————————————————————————————————————————————
C语言自动提供的服务之一是跟踪调用链,那些函数调用了那些函数,当下一个return语句执行后,控制将返回何处等。解决这个问题的经典机制是堆栈中的过程活动记录。过程活动记录是一种数据结构,如下:
局部变量,参数,静态链接(C语言中不使用),指向先前结构的指针,返回地址。
系统尽可能的把过程活动记录的内容放到寄存器中,是函数调用的速度更快。担当函数调用链非常深,寄存器窗口不够用时,寄存器的内容就会被保存到堆栈中保留的活动记录空间中,以便重新利用这些寄存器。
———————————————————————————————————————————————
控制线程
setjmp()和longjmp()是通过上述过程活动记录实现的。goto只能在函数内跳动,而它们可以到函数外。
setjmp保存了程序的计数器和当前的栈顶指针,可能还有一些初始值。longjmp恢复这些值,有效地转移控制并把状态重置回保存状态的时候。
这对函数最大的用途是错误恢复。只要还没有从函数中返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从那里重新开始。相当于C++中的catch和throw。
使用例子:
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
void banana(){
printf("in banana()\n");
longjmp(buf, 1);
printf("you'll never see this");
return;
}
int
main(void){
if(setjmp(buf))
printf("back in main\n");
else{
printf("first time through\n");
banana();
}
return 0;
}
输出:
debian:/home/banyan# ./jmp
first time through
in banana()
back in main
———————————————————————————————————————————————
一些有用的C语言工具:
indent 美化格式,缩进等。
cflow 打印程序中调用者/被调用者关系
dump -Lv 打印动态链接的信息
ldd 打印文件所需的动态库
file 告诉你一个文件包含的内容(如可执行文件、数据、ASCII,shell,script,archive等)
time 显示程序所使用的实际时间和CPU时间。
———————————————————————————————————————————————
附:什么是SVR4?我们为什么要选择SVR4?zz
SVR4是UNIX操作系统的一种新的内核标准,是迄今为止内核版本最新的UNIX
SVR4并不代表一个具体的UNIX变体,而只是一个内核的标准。SVR4有极高的标准性,那意味着你学好了SVR4可以在所有SVR4内核的操作系统上进行统一的操作(不会产生学习了一个UNIX系统还要学习另外的困惑)
SVR4(UNIX System V Release4)是AT&T在1989年首次发行的;SVR4集成SVR3,4BSD,SunOS,以及XENIX的一些特性,还添加了一些新 功能,如实时调度,Korn shell,以及对STREAMS子系统的改进;SVR4是迄今为止最新的UNIX
SVR4的优点如下
1、标准性
符合SVID(AT&T的System V接口定义)、IEEE POSIX规范,以及X/OPEN财团的X/OPEN可移植导引。应该说AT&T公司出品的SVR4是UNIX味儿最浓的UNIX。现在流行的现 代UNIX大多都是基于SVR4的。
2、先进性
AT&T UNIX System V Release4 是迄今为止内核版本最新的UNIX。在这之后USL发行了UNIX SVR4.2,此后又有新的SVR4的发行,其中最新的是SVR4.2/ES/MP。它在SVR4.2的基础上加入了安全性和多处理器的支持,并支持轻量 级进程。(这就是unixware2.1采用的内核)
SVR4.2支持内模块的动态加载(在系统运行中,内核是可以动态变化的)这意味着改变内核而不需要重新启动计算机。
另外,SVR4提供了新的图形用户界面(GUI) -- Motif和sun的openlook(openwindow)。
SVR4.2还增加了对PC新硬件的支持。
3、友好的用户界面
广大的操作系统爱好者往往喜欢从界面的友好性来评价操作系统。
对于字符终端用户SVR4提供的是face界面(OAM)。它将常用的系统管理(如添加新用户、备份…)图形化了。还提供了在线帮助(类似于ScoAdmin)
对于图形终端用户,SVR4提供了openlook标准图形界面。
4、改进的VM(虚拟内存)结构
SVR4的内存管理不再基于原SVR3中“区”的结构,而采用请求分页技术。SVR4采用双表针时钟的页面置换策略,这样的改进降低了页面失效率。
5、改进的进程管理
SVR4支持内核线程、用户线程和轻量级进程。SVR4提供了一组系统调用,它是SVR3和BSD信号功能的超集。同时也支持老的不可靠的信号。
SVR4在进程调度方面做了很多改进,包括:
1)支持要求实时响应的多种应用程序。
2)把调度策略同实现它的机制相分离。
3)应用程序能够控制它的优先级和调度。
4)定义了一个对内核有良好定义接口的调度框架。
5)允许新的调度策略以模块方式加入,包括调度器动态加载的实现。
6)限制临界时间性应用程序的调度延迟。
在进程通信方面SVR4使用流(STREAMS)作为它的基本框架来实现管道(pipes)和有名管道(FIFO)。SVR4的管道是双向的,可同时进行读写操作。
在同步方面,加入了多处理机支持。并用自旋锁代替了信号灯。
6、高级文件系统支持
SVR4除了支持SystemV传统的文件系统s5fs之外,还加入了ufs和vxfs。
Ufs是伯克利快速文件系统,建立在s5fs的基础之上,增加了硬盘的访问速度,并节省了硬盘空间。这种文件系统支持长文件名(大于14个字符)、符号连 接和原子命名。并支持片段(slice)就是对磁盘块的进一步划分,用mkfs命令创建文件系统时可以指定slice的大小。一般为1,2,4或8。
Vxfs是Veritas高级文件系统。它是一种日志文件系统,同时提供了许多先进的功能。如系统崩溃的快速恢复、磁盘配额等等
7、设备管理的改进
SVR4支持内核模块的动态加载,具有新的设备驱动程序。内核对驱动程序是透明的,大大简化了驱动程序编写的复杂性。
如果您是一位SVR4的爱好者与支持者,您就应该选择SVR4的UNIX操作系统,如SUN 的 Solaris,IBM的AIX,SCO 的 Unixware等等。