编程的基础知识
编程的基础知识c的发展历史
存的部首void 类型
程序的⼊⼝成了_tmain(),这个和 VC6.0 中的 main 函数类似, 在前⾯加个 t,是为了对 unicode 项⽬的设置兼容,但它们都是程序执⾏的⼊⼝,其中 int argc 是程序的参数个数,_TCHAR* argv[]是参数数组。
程序的编译与链接,PE 格式
⼀个完整的 PE(Portable Executable)⽂件由 DOS 头,PE ⽂件头,块表,块 和调试信息(调试版本有效)组成
在 DOS 头部,以 e_magic 开头,它的值是固定的”0x5a4d”,即(MZ)开头。最开头的 是部分是 DOS 部⾸,DOS 部⾸由两部分组成:DOS 的 MZ ⽂件标志和 DOS stub(DOS 存根程序)。之所以设置 DOS 部⾸是微软为了兼容原有的 DOS 系统下的程序⽽设⽴的。
系统与程序的内存布局
在我们开始内核调试之前,⾸先我们需要对系统的内存内核层与应⽤层的布局有⼀个基本认 识。以 X86 为例,X86 ⽀持 32 位寻址,因此可以⽀持最⼤ 2^32=4GB 的虚拟内存空间(当然 也可以通过 PAE 将寻址空间扩⼤到 64GB,PAE 即 Physical address extension,x86 的处理器增加了额外的地址线以选择那些增加了的内存,所以实体内存的⼤⼩从 32 位增加到了 36 位。 最⼤的实体内存由 4GB 增加到了 64GB)。如下图所⽰,在 4G 的虚拟地址空间中,Windows系统的内存主要分为内核空间和应⽤层空间上下两部分,每部分各占约 2GB,其中还包括了 ⼀个 64KB 的 NULL 空间以及⾮法区域,虚拟地址再通过页表机制映射到物理地址以便存取物理内存中的数据和指令。
X64(AMD64)的内存布局与 X86 的内存布局类似,不同的地⽅在于各⾃空间的范围和⼤⼩不同,同时 X64 下还存在着⼀些空洞(hole)。在 X64 内存理论上⽀持最⼤ 2^64的寻址空间,但实际上这个空间太⼤了,⽬前根本⽤不完,因此实际上的 X64 系统⼀般都只⽀持到 40多位(⽐如Windows⽀持44位最⼤寻址空间为16TB,Linux ⽀持48位最⼤寻址空间256TB 等),⽀持的空间达到了 TB 级别。但是,⽆论是在内核空间还是在应⽤层空间,这些上 TB的空间并不都是可⽤的,存在着所谓的空洞(HOLE)。
Bit 与 Byte
1byte=8bit
1 个 bit 只能存储
2 个信息:0,1
1 个 byte 能存储:2^8-1 个信息:【-128,127】or【0,255】
数据存储位置:寄存器,内存,磁盘等
整数的编码与存储
整数包括负数,零,和正数。计算机中的整数分为有符号数和⽆符号数。有符号数的最⾼位表⽰符号:即最⾼位为 0,表⽰正数,最⾼位为 1,表⽰负数。⽆符号数表⽰⾮负数,整个位数都⽤来表⽰整数的值。 如果⽤ N 位来表⽰整数,那么有符号数的范围为: [-2^(N-1),(2^(N-1))-1];⽆符号数的表⽰范围为[0,(2^N)-1]。⽐如,⽤ 8 位来表⽰有符号整数,由于第 8 位⽤于表⽰了符号,因此,整数的表⽰范围为[-128,+127];如果是表⽰⽆符号整数,则表⽰范围为[0,255]。
整数的编码
整数的编码分为原码、反码、和补码。计算⾥使⽤的是补码的存储⽅式。
对于 8 位整数来说,补码的表⽰范围为[-128, 127]
那么有了原码,计算机为什么还要⽤补码呢?
补码的设计⽬的是:
⑴使符号位能与有效值部分⼀起参加运算,从⽽简化运算规则。
⑵使减法运算转换为加法运算,进⼀步简化计算机中运算器的线路设计。
此外,在补码中⽤-128 代替了-0,所以没有+0 和-0 之分,符合常理,所以补码的表⽰范围
为: -128~0~127 共 256 个。
注意:-128 没有相对应的原码和反码,-128 的补码为:10000000
注意:-128 没有相对应的原码和反码,-128 的补码为:10000000
整数的存储
整数的存储分为⾼位优先存储(big-endian)和低位优先存储(little-endian)
⾼位优先存储:⾼位⾸先存在低地址。
低位优先存储:低位⾸先存在低地址。
假设⼀个 32 位整数的值为 25000。25000 的补码为: 0x000061a8,共 4 个字节(注意到, 在⼗六进制中,2 个数为⼀个字节),其中最左边的 00 是最⾼位,然后依次为 00 次⾼位, 61 次低位,a8 低位。 那么在内存中如何存放这 4 个字节呢?也就是内存中的低地址是优先存放最⾼位还是最低位呢? 下图是这⼀个整数的低位优先和⾼位优先的存储实例:
在上图中,⾼位优先的系统中,会优先把⾼位的 00 存放在低地址;⽽低位优先的系统正好 相反,将低位 a8 优先存放在内存中的低地址。
如何判断⼀个系统是低位优先或者⾼位优先? ⾸先,来看整数 1 在⾼位优先和低位优先的系统中的存储。
给出下⾯ 2 种判断⽅法的代码:
//第⼀种⽅法:
bool is_integer_lower_store()
{
int x = 0x1;
char *p = (char *)&x;
if (*p == 1)
return true;
else
return false;
}
/
/第⼆种⽅法:
typedef union {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。