新书入帐:W. Richard Stevens 系列

W. Richard Stevens系列就不多说了。

W. Richard Stevens对UNIX系列程序员的影响是不言而喻的,他的书本本经典。丰富的知识面,严谨的思维。

他的书可谓是UNIX程序员必备!

很惭愧学计算机后这么长事件后才把这套书收全,这次收的有:

TCP/IP详解 1-3卷

UNIX网络编程 1, 2卷

UNIX环境高级编程

最后缅怀下这位程序设计巨匠,谢谢您。

[阅读全文] »

/etc/issue文件定制

/etc/issus文件是用于显示登录前信息的。如:
This is XXX(Linux x86_64 2.6.36-gentoo-r3) 23:10:30
GENTOO系统自带的/etc/issue.logo文件的效果特棒。但是个人不是很喜欢紫色。修改了一下。效果如图。

issue

DIY GENTOO ISSUE

issus.logo文件每行前面有这么类似于^[[0;34;40m这样的编码。
这里的^[[表示接下来的字符需要转义。0;34;40m表示转义编码,期中数字部分编码含义如下表,m表示转义编码结束。编码顺序和数量与显示结果无关,可以随意组合,主要最后以m结束表示编码结束就可以。
编辑完成后可以 cat /etc/issue看下效果,如上图。
这些编码也可以用于echo 命令,例子:

1
echo -e “\033[1;32m Senghoo"

[阅读全文] »

GNU内联汇编详解

关于汇编,一直用的是直接写成库,或者函数。
最近一个小东西需要用到内联汇编,但是发现相关的东西忘的差不多了。复习一下顺便写点东西。

一般格式

1
2
3
__acm__ {
	"汇编代码"
};

这里可以把__acm__替换为acm 但是这种用法不符合ANSI C规范。不推荐使用。
在这种格式中,直接可以使用全局变量如:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
int a,b,r;
void main(){
	a = 10;
	b = 20;
	__acm__{
	"movl a, %eax \n\t"
	"movl b, %ebx \n\t"
	"addl %ebx, %eax \n\t"
	"movl %eax, r \n\t"
	};
	printf("sum is %d",r);
}

使用volatile修饰符可以防止编译器对内联汇编代码优化
[阅读全文] »

《深入理解linux内核》边读边说-内存寻址(二)

硬件中的分段

从80286模型开始,INTEL处理器添加了一种叫保护模式的东西。所以现在的CPU有两种模式:实模式(80286以前CPU运行的模式),保护模式(现代的CPU大部分时间工作的模式)。
CPU刚加电开机的时候处于实模式。这种模式下对内存的寻址是直接使用物理地址寻址。而且可寻址的空间很有限,只有1MB。
经过一定的转换机制后CPU进入保护模式(CR0寄存器的PE为置1,PE位为CR0寄存器的第0位),保护模式中,CPU的寻址能力得到扩展能使用所有的可用内从空间。
实模式存在的主要原因是为了保持和以前处理器的兼容(现在都32年过去了,还得和1978年的8086CPU保持兼容。。。。),并且让操作系统自举。
保护模式相关更多信息请看:http://en.wikipedia.org/wiki/Protected_Mode

段选择符和段寄存器

CPU中有6个段寄存器分别是:CS,DS,SS,ES,FS,GS。
这些中三个寄存器有专门的用途:
CS:代码段寄存器,可执行的指令就包含在这里,执行时SC:IP指向要执行的指令(当前执行)。
SS:栈段寄存器,程序的栈就在这个段。
DS:数据段寄存器,保存程序执行时的数据。
其他寄存器可以用做任意用途。
这里简单说一下没启用保护模式的时候分段机制。
没启用保护模式的时候段寄存器直接存储地址的高16位,而偏移表示底16位。
也就是物理地址=段寄存器*16+偏移地址
开启保护模式后段寄存器保存的就不是简单的保存物理地址高位,而是保存叫段选择符(Segment Selector)的东西。
PS:以下注意段选择符,段描述符,这两个是不同的,分别用于选择和描述一个段。
段选择符的结构如图:

Segment Selector format

Segment Selector format

[阅读全文] »

《深入理解linux内核》边读边说-内存寻址(一)

内存地址

内存地址有三种类型:逻辑地址,线性地址,物理地址。
逻辑地址:常见程序所表示的地址就是逻辑地址。比如MS-DOS程序设计时使用DS:EAX,CS:IP等地址都是逻辑地址。此类地址把地址分为段偏移的模式来把程序分为若干段。在逻辑地址层面上可以把内存看为若干个段来分开的空间。
线性地址:线性地址是32位整数。是逻辑地址通过分段单元转换后的结果。在线性地址上可以把内存看为0×00000000到0xfffffff的线性空间。
物理地址:芯片级寻址用的地址。与地址总线上的电信号对应。

刚开始突然接触三种地址有点晕,可以这么理解:
比如把内存比喻成几本书落在一起。
逻辑地址的模式是,第X本书的第Y页的内容。
线性地址的模式是:从头数,第XX页的内容。
物理地址的模式是:从头开始测量第N毫米的页的内容。
虽然这种比喻在后面的说实际工作模式的时候会发现不太正确。但是现在对于理解三种地址还是有些帮助的。
CPU和内存真正进行数据交换的时候需要使用物理地址,而一般程序所使用的是逻辑地址。可能会有疑问为什么会进行两次转换,而不是一次转换搞定的策略,这个问题在接下来的分析中会浮出水面。

[阅读全文] »

Page 3 of 9«12345»...Last »