基础知识

机器语言

机器语言是 011 组成的,能直接对 CPU 发送指令的语言。早期程序员通过卡片打孔控制机器。这样的程序难以编辑。

汇编语言的产生

汇编语言和机器语言是逐行一一对应的。例如:

  • 操作:寄存器BX内容放进AX
  • 机器:1000100111011000
  • 汇编:mov ax, bx

寄存器就是 CPU 中可以存储数据的原件, AX 和 BX 都是寄存器代号。

汇编语言需要通过编译器转换成机器码。

汇编语言的组成

  1. 汇编指令:实际的操作指令,直接转换成机器码
  2. 伪指令:类似 C 中的 #define, 没有对应的机器码,编译器负责执行
  3. 其他符号:例如 + – * /

存储器

就是内存,存储指令和数据。

指令和数据

在内存或者磁盘上都是一样的二进制编码,根据冯诺依曼结构,有的看做指令,有的看做数据。

例如

  • 内容:1000100111011000
  • 数据:89D8H
  • 程序:mov ax, bx

存储单元

从 0 开始编号, 8bit = 1byte 。

CPU 对存储器的读写

需要提供以下信息:

  • 存储单元的地址信息
  • 读写、器件的控制信息
  • 数据信息

通过总线传递数据。

地址总线

其宽度决定了能发送的地址位长度。

数据总线

同理,一次传输总线宽度位。

控制总线

CPU 能发送的对器件的控制代码。

内存地址空间

CPU 的地址总线宽度为 10 ,可以寻址 1024 个内存单元,这就对应内存地址空间。

可以把后面提到的各种存储器都看做同一个逻辑存储器。把地址段不同部分分配给不同的器件。

主板

通过总线和插槽链接器件。

接口卡

CPU 可以发送控制和数据读写命令。如显卡。

存储器芯片

  • 随机存储器
  • BIOS 和 ROM
  • 接口卡上的 RAM

寄存器

功能:

  • 运算器处理信息
  • 寄存器存储信息
  • 控制器控制器件
  • 内部总线传输数据

8086 有 14 个寄存器,分别是 AX BX CX DX SI DI SP BP IP CS SS DS ES PSW 。

通用寄存器

有 AX BX CX DX ,分别有 16 位,可以分开当 AH AL 这样的高低位使用,互不影响。

字在寄存器中的存储

一个字 Word 16 位 = 两个字节 Byte 8 位。

一些汇编指令

  • 汇编 mox ax, 18 高级语言 AX=18
  • 汇编 add ax, 8 高级语言 AX = AX+8
  • 汇编 add ax, bx 高级语言 AX=AX+BX

物理地址

需要通过逻辑地址计算得出

16位结构CPU

8086 是 16 位的,特点:

  • 运算器一次出处理 16 位数据
  • 寄存器最大宽度 16 位
  • 寄存器、运算器通路 16 位

8086 得到物理地址

有 20 位地址总线,1MB寻址能力,但是内部能处理的地址只有16位。但是可以合成20位地址。

  • 提供段地址和偏移地址
  • 利用地址加法器相加

准确的说,物理地址=段地址x16+偏移地址。

段的概念

内存并没有分段,但是 CPU 做了分段。但是分段可以是任意自己制定的。

段寄存器

CS DS SS ES

CS和 IP

CS 是代码段寄存器, IP 是指令指针寄存器,任意时刻执行的代码就是 CS:IP 。

修改CS和IP的指令

不能够直接 mov 修改,如果同时修改用
JMP 段地址:偏移地址 ,只修改 IP 的话用 JMP 某个寄存器

代码段

代码会被自动存入内存,但是并不会被 CPU 自动识别为指令而非数据,所以需要 JMP 跳到代码段开头。

寄存器

内存中字存储

字单元 DWORDL两个连续的内存单元,高地址存高位,低地址存地位。例如数据 20000 = 4E20H , 0 位存 20H (低), 1 位存 4EH (高)。

DS 和[address]

DS 通常存要访问的数据的段地址。

mov bx, 1000H     ; ds 是不能直接放入数据的,所以要用 bx 中转。
mov ds, bx        ; 段地址
mov al, [0]       ; [0]默认是基于ds的偏移,所以实际上代表 1000:0 位置。

字的传送

只要目标是 16 位就行。

mov add sub 指令

mov 寄存器 数据/寄存器/内存单元
mov 内存单元/段寄存器 寄存器

记住何时需要寄存器中转即可。

数据段

用 ds 存放数据段段地址, 用 [] 缩写访问偏移。

CPU 提供的栈机制

SS:SP 指向栈顶, SS 指向栈。

PUSH AX 进, POP AX 出。

例如,初始状态 SS=1000H , SP=0020H, SS:SP=10020H 也就是栈底。 PUSH 8 次字 (占位置 16 字节, 10H 个位置) 后, SS:SP=10010H 。

8086 没有保证栈不超界的设计。

第一个程序

源码从写出到执行

  1. 编写代码
  2. 编译连接:可执行文件包括描述信息和程序本身
  3. 执行

源程序

assume cs:codeseg       ; 关联寄存器和代码段
codesg segement         ; 定义语句段...mov ax,4c00Hint 21H              ; 程序返回
codeseg ends
end

编译和连接

根据具体使用IDE而定。

BX 和 loop 指令