1. 基础知识

概念

  • 汇编语言
    • 汇编语言是机器指令的助记符,每一种CPU都有自己的汇编指令集
    • 组成
      1. 汇编指令:机器指令的助记符,有对应的机器码
      2. 伪指令:由编译器执行,没有对应机器码,机器不执行
      3. 其他符号
  • 存储单元

    • 微型机存储单元可以存储一个B(Byte,字节),即8个二进制位,存储无符号值0~255
  • 总线

    • 计算机中专门连接CPU和其他芯片的导线,称为总线。导线从物理上讲,就是一根根导线的集合,一根导线可以传送的稳定状态只有两种,高电平或低电平,分别可以代表1和0。
    • 带宽:一个CPU有N跟总线,可以称总线的宽度为N。
    • 根据传送的信息不同,总线从逻辑上又分为,地址总线,控制总线和数据总线。
    • 地址总线:地址总线的宽度决定了CPU的寻址能力
      • 寻址范围为2^N -1
      • 寻址能力为2^N
    • 数据总线:数据总线的宽度决定了CPU与其他部件进行数据传送石一次的数据传送量
    • 控制总线:控制总线的宽度决定了CPU对系统中其他器件的控制能力
  • 内存地址空间

    • CPU在操纵不同器件时,把他们都当作内存来对待,把所有物理存储器总的看作一个由若干个存储器组成的逻辑存储器,每个物理存储器在这个逻辑存储器中占有一个地址段,即一段地址空间。把这个逻辑存储器称作内存地址空间。

CPU对存储器的读写

  • CPU要想进行数据的读写,必须通过总线与外部器件(芯片)进行下面3类信息的交互
    • 地址信息,存储单元的地址
    • 控制信息,器件的选择,读或写的命令
    • 数据信息,读或写的数据

例:CPU从3号单元读取数据

  1. CPU通过地址线将地址信息3发出
  2. CPU通过控制线发出命令,选中存储器芯片,并发出读取数据的指令
  3. 存储器将3号单元中的数据通过数据线送入CPU

机器码:10100001 00000011 00000000 汇编指令:MOV AX,[3]

存储容量的转换

  • 地址总线宽度和寻址能力的转换
  • 数据总线宽度和数据一次传送能力

 

2. 寄存器

这里的寄存器,研究的是8086CPU的寄存器。

8086CPU有14个寄存器分别是:

AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW

这些寄存器都是16位的,存放两个字节

2.1 通用寄存器

有AX(accumulator)、BX(base)、CX(count)、DX(data)

8086上一代CPU(8080、8085)是8位的,为了保证兼容,这四个寄存器每个都可以分为两个独立使用的寄存器

  1. 如AX分为AH和AL(高八位和低八位)
  2. BX分为BH和BL
  3. CX分为CH和CL
  4. DX分为DH和DL

2.2 字在寄存器中的存储

一个字由两个字节组成:

汇编语言笔记整理

2.3 几条汇编指令

(汇编指令及寄存器名称不区分大小写,用16进制表示二进制)

例1

汇编语言笔记整理

例2

汇编语言笔记整理

注意:1. 数据超过存储器内容,会导致高位数据丢失

   2. 当16位寄存器看做独立的8位寄存器时,操作不会对16位寄存器产生影响

2.4 物理地址

所有的内存单元构成的存储空间是一个一位线性空间,每一个内存单元都在这个空间有唯一的地址,把每个内存单元唯一的称作物理地址。

2.5 16位的CPU

  1. 运算器一次最多可以处理16位的数据
  2. 寄存器最大宽度是16位
  3. 寄存器与运算器之间的通路是16位

2.6 8086CPU给出物理地址的方法

8086CPU有20根地址总线,有1MB的寻址能力,但在内部一次性处理、传输、暂时存储的地址为16位,顾8086CPU在内部采取用两个16位地址合成的方法来形成一个20位的地址。

汇编语言笔记整理

地址加法器采物理地址 = 段地址×16 + 偏移地址 的方法合成物理地址

2.8 段的概念

在编程时根据需要,可以把一些内存看做一个段,用段地址×16定位段的起始地址,用偏移地址定位段中的内存单元

可以看做一段的内存需要符合下面几个要求:

  1. 地址连续
  2. 起始地址为16的倍数
  3. 最大长度小于64KB

2.9 段寄存器

8086CPU提供4个段寄存器:CS(Code Segment)、DS(Data Segment)、SS(Stack Segment)、ES(Extra Segment)

2.10 CS和IP

CS:IP是CPU中最重要的两个寄存器,他们指示了CPU当前要执行的指令地址,CS为代码段寄存器存放指令的段地址,IP(Extra Segment)为指令指针寄存器存放指令的偏移地址,

8086CPU工作过程:

  1. 从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器
  2. IP=IP+所读指令的长度,从而指向下一条指令
  3. 执行指令转到步骤 1

注意:内存中的信息可以看做指令或数据,CPU将CS、IP中的内容看做指

2.11 修改CS、IP的指令

在CPU中,程序员能够用指令读写的部件只有寄存器,程序员需要通过改变CS、IP中的内容实现对CPU的控制。

mov指令(传送指令)不能用于设置CS、IP中的值,能够改变CS、IP值的指令统一称为转移指令、

jmp指令:

  1. jmp 段地址:偏移地址。用指令中给出的段地址修改CS,偏移地址修改IP
  2. jmp 某一合法寄存器。用寄存器中的值修改IP

2.12 代码段

专门用来存储指令的内存区域,需要用CS:IP指向才可以执行。

总结

  1. CPU访问内存单元时,必须提供内存单元的物理地址。8086CPU在内部用段地址和偏移地址移位相加的方式形成最终的物理地址。
  2. 段地址在段寄存器中存放,8086CPU中CS存放指令的段地址,IP存放指令的偏移地址,任意时刻CPU将CP:IP中的地址当做指令执行。
  3. 8086CPU工作过程
    1. 从CS:IP指向的内存单元读取指令,读取的指令放入指令缓存器
    2. IP指向下一条指令
    3. 执行指令(转到1,重复这个过程)

 

实验:基本指令

  • R命令(Register):
    R, R [register name]。显示和修改寄存器内容。

  • D命令(Dump):
    D [address], D [range]。内存16进制显示。

  • E命令(Enter):
    E address[list]。修改内存字节

  • A命令(Assemble):
    a [adress]。逐行汇编。

  • U命令(Unassemble):
    U [address], range。查看汇编代码(反汇编)。

  • T命令(Trace):
    T [=address][value]。跟踪执行。

 

3. 寄存器内存访问

3.1 内存中字的存储

CPU中,用16位来存储一个字,高八位存储高位字节,低八位存储低位字节,即一个字需要两个地址连续的内存单元存放。

我们把组成的内存单元叫做字单元,以后把起始地址为N的字单元简称为N地址单元。

 

3.2 DS和[address]

读取10000H单元的数据,[address]表示一个偏移地址为address的内存单元

mov bx,10000H

mov ds,bx // 把DS设为10000H

mov al,[0] // 这时候[0], 就是取1000H:0的意思

 

注意:8086CPU不支持直接将数据送入段寄存器,需要先把数据放在一个通用寄存器,再移动到段寄存器

 

3.3 字的传送

 

3.4 mov、add、sub的指令

例:

mov ax,8

mov ax,bx

mov ax,[0]

mov [0],ax

mov ds,ax

mov ax,ds

mov ds,[0]

 

3.5 数据段

可以专门用DS来存放数据段的段地址

 

3.6 栈

 

3.7 CPU提供的栈机制

任意时刻,SS:SP指向栈顶元素

push ax指令

1)SP=SP-2

2)向SS:SP指向的字单元中送入数据

 

pop ax

1)将SS:SP指向的字单元读取数据

2)SP=SP+2

 

3.8 栈顶超界的问题

8086CPU没有设置防止栈溢出的机制,需要自己注意

 

实验二:栈

汇编语言笔记整理

 

注意:

Debug的T命令在执行修改器SS的指令时,下一条指令也紧接着被执行

 

4. 第一个程序

开始编完整的汇编程序

4.1 写出到执行

  1. 编写汇编源程序(用 Edit或记事本等,文件保存为.asm)
  2. 对源程序进行编译(用masm.exe对源程序进行编译,生成 .obj文件)
  3. 链接(用link.EXE文件进行链接,生成 .exe文件)
  4. 执行

汇编语言笔记整理

4.2 源程序包括伪指令和汇编指令

assume cs:codesg // 将段寄存器cs和codesg关联起来

// 定义一个段,一个汇编程序由多个段组成,这些段用来存放代码、数据或当做栈空间来使用。如下简单的实例中最少有一个段来存放代码

codesg segment //  一个段的开始, codesg 为段名称

mov ax,0123H

mov bx,0456H

add ax,bx

mov ax,4c00H  // 将程序对CPU的控制权交出

int 21H

codesg ends    //  codesg段的结束

end   //  汇编程序的结束

  1. 伪指令

2. 程序(汇编指令)

3. 标号:比如说codesg。一个标号指代了一个地址

4. 程序返回

4.3 操作系统的外壳(shell)

任何通用的操作系统都要提供一个称谓shell的程序,用户(操作人员)使用这个程序来操作计算机系统进行工作。DOS的shell称作命令解释器,command.com,DOS启动时,先完成其他重要的初始化工作,然后运行命令解释器程序command,将exe文件加载入内存,而且Command设置CS:IP指向程序的第一条指令,使程序可以运行,最后程序返回时,返回到command中,CPU继续运行command。

4.4 程序被装入内存什么地方?

————程序的加载过程

汇编语言笔记整理

  1. 程序程序加载后,ds中存放着程序所在内存区域的段地址,并且偏移地址为0
  2. PSP(前缀数据区:用来和程序进行通信)段地址SA是ds, PSP占256个字节,可得程序的物理地址是:

SA+10H:0

实验三:编程编译连接跟踪

汇编语言笔记整理

 

5 [BX]和loop指令

5.1 [bx]和内存单元

[bx]相当于用寄存器起变量的作用做偏移地址,注意他的段地址是DS

在debug程序中 mov al,[6]表示吧六号内存单元的值放入al,在汇编程序中需要mov bx,6 再mov al,[bx]

 

段前缀(ds:,cs:,ss:,es:)

形式 mov ax,cs:[bx] //用来显示的声明段地址

如果不加段前缀, 直接 mov ax,[bx] 则默认段前缀为ds:

5.2 约定

  1. 描述性符号():(地址或寄存器)表示里面的内容
  2. idata表示常量

5.3 循环指令loop

assume cs:code

code semgent

mov ax,0

mov cx,236 //cx循环次数

s: add ax,123 //循环标号 s: 标示一个地址存放需要循环的语句

loop s //开始循环

mov ax,4c00h

int 21h

code ends

end

 

5.4 debug

g 命令+偏移地址 跳到cs:编译地址所存代码行

p 命令 遇见loop语句直接跳到循环结束

 

实验4 [bx]和loop

 

 

汇编语言笔记整理

注意1

将0:200用0020:0 表示

bl把低八位赋值到0020:[bx]

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章: