这两天忙于做数模的课程作业,因此去图书馆的时间少了,周末去了两个晚上,看了两章,关于字符处理和CPU、内存的组织,现将笔记整理如下(大部分是摘抄的原文,也有自己加以提炼的)。
1.ASCII字符集中大小写字母仅第五位有差别(最低位编号为0),大写字母是0,小写字母是1。因此在进行字符大小写转换时应用位运算代替加减法。
2.ASCII字符集分为4个组,每组32个字符。第一组是非打印字符,即控制字符;第二组是各种标点、特殊字符和数字;第三组是大写字母和6个特殊符号;第四组是小写字母、5个特殊符号和1个控制字符“删除”(delete)。
3.Unicode支持用户自定义字符,因此当你想要自定义一个多于256个字符的字符集时,可以优先考虑使用Unicode的用户自定义码点(字符集),当然你也可以完全自定义,具体可参考《深入理解计算机》第五章。
4.处理器数据总线的根数和最大的通用整数寄存器中较小的一个决定处理器的大小。
5.有些16位CPU将内存组织成两个“列”:一个偶数列(地址编号为0,2,…)和一个奇数列(地址编号为1,3,…),偶地址上的字节出现在数据线D0——D7(低端字节),奇地址的字节出现在D8——D15(高端字节)。而地址总线上总是传递偶地址,这导致访问奇地址的字(两个字节)时需要2次访问内存操作。比如说CPU要读地址125处的字,它会先读124和126处的字,然后交换124的高端和126的低端(由于前面提到的数据线传输的特性)以得到125处的字。
6.拥有32位内存接口的CPU,其地址总线中的地址总是4的倍数,但是通过使用不同的字节使能控制线,CPU可以选择该地址处4个字节中的任何一个使用。但是当访问编号满足模4余3的地址的字时,和16位的类似,也需要两次内存操作。因此一般来说,字的低端字节(起始地址)最好在偶数地址,双字则是4的倍数。
7.大多数RISC CPU要求所有的数据访问的大小与CPU的大小一致(Intel的CPU属于CISC),通常是双字访问。如果需要访问字节或字时则需要额外的代价来处理。因此如果希望软件能很好地运行在各种现代RISC CPU的机子上,最好使用双字数据,而避免使用字数据。
8.内存组织有小端组织和大端组织的区别。小端组织即将低端地址作为基地址存放数的低位,而大端组织正好相反。因此对双字在大小端格式(不同的CPU可能会有这种区别)之间进行转换时需要进行镜像转换,即第0个字节和第3个字节对换,第1个和第2个字节对换。为了方便操作,通常可以使用union数据类型(C)来存储大对象(DWORD),还可以用这个方法来检测一台机子的CPU是小端组织还是大端组织,如下:
#include <stdio.h>
int main()
{
union bigObject
{
unsigned long data;
unsigned char d[4];
} testData;
{
union bigObject
{
unsigned long data;
unsigned char d[4];
} testData;
testData.d[0] = 0;
testData.d[1] = 1;
testData.d[2] = 0;
testData.d[3] = 0;
testData.d[1] = 1;
testData.d[2] = 0;
testData.d[3] = 0;
if(testData.data == 256)
{
printf("This memory is small-ended./n");
}
else if(testData.data == 65536)
{
printf("This memory is big-ended./n");
}
else
{
printf("Test failed...Modify it./n");
}
return 0;
}
{
printf("This memory is small-ended./n");
}
else if(testData.data == 65536)
{
printf("This memory is big-ended./n");
}
else
{
printf("Test failed...Modify it./n");
}
return 0;
}
( To be continued... )