一,编程的层次
数字逻辑(Level 1):二进制数值机器语言。
指令集架构(Level 2):计算机芯片制造商在处理器内部设计一个指令集来实现基本操作,如传送、加法或乘法。这个指令集也被称为机器语言。每一个机器语言指令或者直接在机器硬件上执行,或者由嵌入到微处理器芯片的程序来执行,该程序被称为微程序。
汇编语言(Level 3):在 ISA 层,编程语言提供了一个翻译层,来实践大规模软件开发。汇编语言出现在 Level 3,使用短助记符,如 ADD、SUB 和 MOV,易于转换到 ISA 层。汇编语言程序在执行之前要全部翻译(汇编)为机器语言。
高级语言(Level 4):Level 4 是高级编程语言,如 C、C++ 和 Java。这些语言程序所包含的语句功能强大,并翻译为多条汇编语言指令。比如,查看 C++ 编译器生成的列表文件输出,就可以看到这样的翻译。汇编语言代码由编译器自动汇编为机器语言。
二,字节
在 x86 计算机中,所有数据存储的基本单位都是字节(byte),一个字节有 8 位。其他的存储单位还有字(word)(2 个字节),双字(doubleword)(4 个字节)和四字(quadword)(8 个字节)。
三,二进制,十进制,十六进制
1.二进制,十进制,十六进制转换教程(https://www.cnblogs.com/summerdata/p/10722144.html)
2.二进制与十六进制
1 | 6 | A | 7 | 9 | 4 |
0001 | 0110 | 1010 | 0111 | 1001 | 0100 |
四,原码, 反码, 补码
1.详解:https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
2.原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。
3.反码,正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
4.补码,正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1 (即在反码的基础上+1)。
五,字符集
1.简介:
如果计算机只存储二进制数据,那么它如何表示字符呢?计算机使用的是字符集,将字符映射为整数。早期,字符集只用 8 位表示。即使是现在,在字符模式(如 MS-DOS)下运行时,IBM 兼容微机使用的还是 ASCII(读为“askey”)字符集。
字符的机内码从0到65535,前128个字符代表英文字母及标准键盘上的字符,128到255个字符代表特殊的字符,如拉丁字母、货币符号、分数等。
ASCII 是美国标准信息交换码(AmeTican Standard Code for Information Interchange)的首字母缩写。在 ASCII 中,每个字符都被分配了一个独一无二的 7 位整数。
由于 ASCII 只用字节中的低 7 位,因此最高位在不同计算机上被用于创建其专有字符集。比如,IBM 兼容微机就用数值 128〜255 来表示图形符号和希腊字符。
Unicode 标准:当前,计算机必须能表示计算机软件中世界上各种各样的语言。因此,Unicode 被创建出来,用于提供一种定义文字和符号的通用方法。
UTF-8
2.详解:字符集和字符编码(Charset & Encoding)(https://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html)
六,基本微机设计
1.模型:
其中:
- 时钟 (clock) 对 CPU 内部操作与系统其他组件进行同步。
- 控制单元 (control unit, CU) 协调参与机器指令执行的步骤序列。
- 算术逻辑单元 (arithmetic logic unit, ALU) 执行算术运算,如加法和减法,以及逻辑运算,如 AND(与)、OR(或)和 NOT(非)。
CPU 通过主板上 CPU 插座的引脚与计算机其他部分相连。大部分引脚连接的是数据总线、控制总线和地址总线。
内存存储单元 (memory storage unit) 用于在程序运行时保存指令与数据。它接受来自 CPU 的数据请求,将数据从随机存储器 (RAM) 传输到 CPU,并从 CPU 传输到内存。
由于所有的数据处理都在 CPU 内进行,因此保存在内存中的程序在执行前需要被复制到 CPU 中。程序指令在复制到 CPU 时,可以一次复制一条,也可以一次复制多条。
总线 (bus) 是一组并行线,用于将数据从计算机一个部分传送到另一个部分。一个计算机系统通常包含四类总线:数据类、I/O 类、控制类和地址类。
数据总线 (data bus) 在 CPU 和内存之间传输指令和数据。I/O 总线在 CPU 和系统输入 / 输出设备之间传输数据。控制总线 (control bus) 用二进制信号对所有连接在系统总线上设备的行为进行同步。当前执行指令在 CPU 和内存之间传输数据时,地址总线 (address bus) 用于保持指令和数据的地址。
时钟与 CPU 和系统总线相关的每一个操作都是由一个恒定速率的内部时钟脉冲来进行同步。机器指令的基本时间单位是机器周期 (machine cycle) 或时钟周期 (clock cycle)。
七,32位寄存器
1.下图展示的是基本程序执行寄存器(basic program execution registers)。8 个通用寄存器,6 个段寄存器,一个处理器状态标志寄存器(EFLAGS),和一 个指令指针寄存器(EIP)。
2.通用寄存器主要用于算术运算和数据传输。一些寄存器的组成部分可以处理 8 位的值。例如,AX 寄存器的高 8 位被称为 AH,而低 8 位被称为 AL。
同样的重叠关系也存在于 EAX、EBX、ECX 和 EDX 寄存器中:
32 位 | 16 位 | 8 位(高) | 8 位(低) |
---|---|---|---|
EAX | AX | AH | AL |
EBX | BX | BH | BL |
ECX | CX | CH | CL |
EDX | DX | DH | DL |
其他通用寄存器只能用 32 位或 16 位名称来访问,如下表所示:
32 位 | 16 位 | 32 位 | 16 位 |
---|---|---|---|
ESI | SI | EBP | BP |
EDI | DI | ESP | SP |
某些通用寄存器有特殊用法:
- EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
- EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。
- ECX 是"计数器"(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
- EDX 是"资料暂存器",总是被用来放整数除法产生的余数。
- ESI 和 EDI 用于高速存储器传输指令,有时也被称为 来源索引(extended source index)寄存器和 目的索引(extended destination index)寄存器。DS:ESI指向源串,而ES:EDI指向目标串
- ESP 用于寻址堆栈(一种系统内存结构)数据。它极少用于一般算术运算和数据传输,通常被称为 堆叠指标(extended stack pointer)寄存器。
- EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:
push ebp ;保存当前ebp
mov ebp,esp ;EBP设为当前堆栈指针
sub esp, xxx ;预留xxx字节给函数临时变量.
...
扩展:
ESP:寄存器存放当前线程的栈顶指针
EBP:寄存器存放当前线程的栈底指针
EIP:寄存器存放下一个CPU指令存放的内存地址
八,64位寄存器
1. 64 位模式下,操作数的默认大小是 32 位,并且有 8 个通用寄存器。但是,给每条指令加上 REX(寄存器扩展)前缀后,操作数可以达到 64 位,可用通用寄存器的数量也增加到 16 个:32 位模式下的寄存器,再加上 8 个有标号的寄存器,R8 到 R15。下表给出了 REX 前缀下可用的寄存器。
操作数大小 | 可用寄存器 |
---|---|
8 位 | AL、BL、CL、DL、DIL、SIL、BPL、SPL、R8L、R9L、R10L、R11L、R12L、R13L、R14L、R15L |
16 位 | AX、BX、CX、DX、DI、SI、BP、SP、R8W、R9W、R10W、R11W、R12W、R13W、R14W、R15W |
32 位 | EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP、R8D、R9D、R10D、R11D、R12D、R13D、R14D、R15D |
64 位 | RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8、R9、R10、R11、R12、R13、R14、R15 |
2.几个保存全局性和任务无关的机器状态的寄存器。
CR0:中包含了6个预定义标志,0位是保护允许位PE(Protedted Enable),用于启动保护模式,如果PE位置1,则保护模式启动,如果PE=0,则在实模式下运行。1位是监控协处理位MP(Moniter coprocessor),它与第3位一起决定:当TS=1时操作码WAIT是否产生一个“协处理器不能使用”的出错信号。第3位是任务转换位(Task Switch),当一个任务转换完成之后,自动将它置1。随着TS=1,就不能使用协处理器。CR0的第2位是模拟协处理器位 EM (Emulate coprocessor),如果EM=1,则不能使用协处理器,如果EM=0,则允许使用协处理器。第4位是微处理器的扩展类型位ET(Processor Extension Type),其内保存着处理器扩展类型的信息,如果ET=0,则标识系统使用的是287协处理器,如果 ET=1,则表示系统使用的是387浮点协处理器。CR0的第31位是分页允许位(Paging Enable),它表示芯片上的分页部件是否允许工作。
CR1:是未定义的控制寄存器,供将来的处理器使用。
CR2:是页故障线性地址寄存器,保存最后一次出现页故障的全32位线性地址。
CR3:是页目录基址寄存器,保存页目录表的物理地址,页目录表总是放在以4K字节为单位的存储器边界上,因此,它的地址的低12位总为0,不起作用,即使写上内容,也不会被理会。
3.x86-64处理器的16个通用寄存器:
寄存器(https://www.jianshu.com/p/57128e477efb)
九,加载并执行程序
在程序执行之前,需要用一种工具程序将其加载到内存,这种工具程序称为程序加载器 (program loader)。加载后,操作系统必须将 CPU 向程序的入口,即程序开始执行的地址。以下步骤是对这一过程的详细分解。
1) 操作系统(OS)在当前磁盘目录下搜索程序的文件名。如果找不到,则在预定目录列表(称为路径(path))下搜索文件名。当 OS 无法检索到文件名时,它会发出一个出错信息。
2) 如果程序文件被找到,OS 就访问磁盘目录中的程序文件基本信息,包括文件大小,及其在磁盘驱动器上的物理位置。
3) OS 确定内存中下一个可使用的位置,将程序文件加载到内存。为该程序分配内存块,并将程序大小和位置信息加入表中(有时称为描述符表(descriptor table))。另外,OS 可能调整程序内指针的值,使得它们包括程序数据地址。
4) OS 开始执行程序的第一条机器指令(程序入口)。当程序开始执行后,就成为一个进程(process)。OS 为这个进程分配一个标识号(进程 ID),用于在执行期间对其进行追踪。
5) 进程自动运行。OS 的工作是追踪进程的执行,并响应系统资源的请求。这些资源包括内存、磁盘文件和输入输出设备等。
6) 进程结束后,就会从内存中移除。
十,I/O 访问层次
- 应用程序调用 HLL 库函数,将字符串写入标准输出。
- 库函数(第 3 层)调用操作系统函数,传递一个字符串指针。
- 操作系统函数(第 2 层)用循环的方法调用 BIOS 子程序,向其传递每个字符的 ASCII 码和颜色。操作系统调用另一个 BIOS 子程序,将光标移动到屏幕的下一个位置上。
- BIOS 子程序(第 1 层)接收一个字符,将其映射到一个特定的系统字体,并把该字符发送到与视频控制卡相连的硬件端口。
- 视频控制卡(第 0 层)为视频显示产生定时硬件信号,来控制光栅扫描并显示像素。