汇编语言<第三版> 王爽 - 笔记
文章目录
简介
编程的平台是硬件不是操作系统.
汇编语言是直接在硬件之上工作的编程语言.
基础知识
操作:寄存器BX的内容发送到AX中
指令:mov ax,bx
寄存器,简单来讲是CPU中可以存储数据的器件,一个CPU有多个寄存器.
AX只是其中一个寄存器的代号.
BX是另一个寄存器的代号.
汇编指令
机器码的助记符,有对应的机器码.
伪指令
没有对应的机器码,有编译器执行,计算器并不执行.
其他符号
+,-,/,*等,由编译器识别,没有对应的机器码.
存储器
CPU是计算机的核心部件,想要CPU工作就应该对它提供指令和数据。
指令和数据在存储器中存放,也就是内存.
指令和数据
在内存和硬盘上,指令和数据没有区别,都是二进制数据.
cpu在工作的时候把有的信息当做指令,有的信息当做数据.
存储单元
存储器被划分成若干个存储单元,每一个存储单位从0开始顺序编号,例如一个存储器有128个存储单元,它的编号就是0~127.
一个二进制位等于1bit.
8bit == 1byte(字节).
一个存储单元可以存储1byte(8bit)
一个存储器有128个存储单元就可以存储128个byte.
CPU对存储器的读写
存储单元的编号可以看做存储单元在存储器中的地址.
CPU要从内存中读取数据,首先要指定存储单元的地址.
CPU在读写数据时还要指定对哪个部件进行操作,进行哪种操作,是从中读取数据,还是向里面写入数据.
如果CPU要进行数据读写,必须和外部芯片进行3大类信息的交互.
- 存储单元地址(信息)
- 器件(芯片)的选择,读或写的命令(控制信息)
- 读或写的数据(数据信息)
CPU是通过地址总线,控制总线以及数据总线传送数据到存储器的芯片中.
-
CPU通过地址线将地址信息
3
发出. -
CPU通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据.
-
存储器将3号单元中的数据
8
通过数据线送入CPU.
写操作与读操作类似,比如向3
号单元写入数据26
CPU通过地址线将地址信息3
发出.通过控制线发出内存写命令,选中存储器芯片并通知它要写入数据.
CPU通过数据线把数据26
写入内存3号单元中.
汇编命令:mov AX,[3] 把3号单元的内容传入AX
地址总线
CPU通过地址总线来指定存储器单元.地址总线上能传送多少不同的信息,CPU就可以对多少个存储单元进行寻址.
假设一个CPU有10根地址总线.在电子计算机中一根导线有两种状态,高电平或低电平.
用二进制表示就是1
或0
,10根导线就可以传送10
位二进制数据
假如CPU有N
根地址总线.那么这个CPU的地址总线宽度为N
.这样CPU最多可以寻找2的N次方个内存单元.
数据总线
CPU与内存或其他器件之间的数据传送是通过数据总线来进行的,数据总线的宽度决定了CPU和外界的数据传送速度.
8根数据总线一次可以传送一个8位(1字节)的二进制数据.16根数据总线一次可传送2个字节.
8088CPU的数据总线宽度为8,8086CPU的数据总线宽度为16
案例:向8088CPU内存中写入数据89D8H
案例:向8086CPU内存中写入数据89D8H
8086有16根数据总线,可一次传送16位数据.
8088有8根数据总线,一次只能传送8位数据,所以进行二次数据传送.
控制总线
CPU对外部器件的控制是通过控制总线来进行的.
有多少根控制总线就意味着CPU提供对外部器件的多少种控制,所以控制总线宽度决定了CPU对外部器件的控制能力。
内存读命令是由一根为读信号输出
的控制线由CPU向外传送读信号.CPU向该控制线上输出低电平时表示将要读取数据
内存写命令是由一根为写信号输出
的控制线则负责传送写信号.
小结
- 汇编指令是机器指令的助记符,同机器指令一一对应.
- 每一种CPU都有自己的汇编指令集.
- CPU可以直接使用的信息在存储器中存放.
- 在存储器中的指令和数据没任何区别,都是二进制数据.
- 存储单元从零开始编号.
- 一个存储单元可以存储8个bit,即8 为二进制数.
- 1Byte = 8bit 1KB = 1024byte 1MB = 1024KB 1G = 1024MB
- 地址总线的宽度决定了CPU的寻址能力.
- 数据总线的宽度决定了CPU与其他器件进行数据传送时的一次数据传送量。
- 控制总线的宽度决定了CPU对系统中其他器件的控制能力.
检查点
- 1个CPU的寻址能力为8KB,那么它的地址总线宽度为
13
- 8KB = 1024B * 8 = 8192
- 8192 / 2 = 2^N = 13
- 1KB的存储器有
1024
个存储单元,存储单元编号从0
到1023
- 一个存储单元占1byte(8bit) 1KB = 1024byte
- 1KB的存储器可以存储
8192
bit,1024
个byte.
- 1KB = 1024byte 1byte = 8bit.
- 1024byte * 8bit = 8192
- 一个存储单元占1byte(8bit) 1KB = 1024byte
- 1GB,1MB,1KB分别是
1073741824,1048576,1024
byte
- 1GB = 2^30,1MB = 2^20,1KB = 2^10
- 8080,8088,80286,80386的地址总宽度分别为16根,20根,24根,32根,则它们的寻址能力分别为
64KB
,1MB
,16MB
,4GB
- 8080,8088,8086,80286,80386的数据总宽度分别为8根,8根,16根,16根,32根,则它们一次可以传送的数据为
1Byte
,1Byte
,2Byte
,2Byte
,4Byte
- 从内存中读取1024字节的数据,8086至少要读
512
次,80386要读256
次. - 在存储器中,数据和程序以
二进制
形式存放.
内存地址空间
一个CPU的地址总线宽度为10,那么可以寻址1024个内存单元.这1024个内存单元就构成了这个CPU的内存地址空间.
主板
主板上有核心器件和一些主要器件,这些器件通过总线(地址,数据,控制总线)相连,这些器件有CPU,存储器,外围芯片组,扩展插槽等.扩展插槽上一般插有RAM内存条和各类接口卡.
接口卡
计算机系统中,所有可用程序控制其工作的设备,必须受到CPU的控制,CPU对外部设备不能直接控制,如显示器,音箱,打印机等.直接控制这些设备进行工作的是插在扩展插槽上的接口卡
.扩展插槽通过总线和CPU相连,所以接口卡也通过总线同CPU相连,CPU可用直接控制这些接口卡,从而实现CPU对外设的间接控制.简单来讲就是CPU通过总线向接口卡发送命令,接口卡根据CPU的命令控制外设进行工作.
各类存储器芯片
随机存储器(RAM)
- 可读可写,但必须带电存储
- 关机后存储的内容丢失.
- 用于存放供CPU使用的绝大部分数据和程序.
- 主随机存储器一般有两个位置上的RAM组成,装在主板上的RAM和插在扩展槽上的RAM.
- 接口卡上的RAM
某些接口卡需要对大批输入,输出数据进行暂时存储,在其装上RAM.最典型的就是显卡上的RAM(显存).显卡随时将显存中的数据向显示器上输出.换句话说,我们将需要显示的内容写入显存,就会出现在显示器上.
只读存储器(ROM)
- 只能读取不能写入
- 关机后其中的内容不丢失.
- 装有BIOS的ROM
BIOS是由主板和各类接口卡厂商提供的软件系统,可以通过它利用该硬件设备进行最基本的输入输出.在主板和某些接口卡上存储相应的BIOS的ROM。例如,主板上的ROM中存着主板的BIOS,显卡的ROM存储着显卡的BIOS,如果网卡上装有BIOS,那其中就可以存储网卡的ROM.
内存地址空间
上述的那些存储器,在物理上是独立的器件,但是在以下两点上相同
- 都和CPU的总线相连
- CPU对他们进行读或写的时候都通过控制线发出内存读写命令
CPU在操控它们的时候,把它们当内存对待,把它们总看成一个由若干存储单元组成的逻辑存储器,就是我们所说的内存地址空间.
在逻辑图中所有的物理存储器都被看作一个由若干存储单元组成的逻辑存储器。每个物理存储器在这个逻辑存储器占有一个地址段,即一段地址空间.CPU在这段地址空间中读写数据,实际上就是在相对应的物理存储器中读写数据.
假设逻辑图中的内存地址段分配如下
逻辑存储器 | 地址段 | 空间 |
---|---|---|
主随机存储器 | 0~7FFFH | 32KB |
显存 | 8000H~9FFFH | 8KB |
ROM | A000H~FFFFH | 24KB |
CPU向内存地址为100H
的内存单元中写入数据,这个数据就被写入主随机存储器中.
CPU向内存地址为8000H
的内存单元写入数据,这个数据就被写入显存中,然后会被显卡输出到显示器.
CPU向内存地址为C00H
的内存单元写入数据的操作是没有结果的,C00H
单元中的内容不会改变,实际上就是ROM存储器中的一个单元》
内存地址空间大小受CPU地址总线宽度的限制,8086CPU的地址总线宽度为20,可以传送220个不同的地址信息(大小从0~220 - 1).即可以定位2^20个内存单元.则8086PC的内存地址空间大小为1MB,同理80386CPU的地址总线宽度为32,则内存地址空间最大为4GB;
不同计算机系统的内存地址空间分配情况是不同的,比如我们希望在显示器上输出一条信息,要向显存中写入数据,必须知道显存在地址空间中的地址.
寄存器
CPU由运算器,控制器,寄存器等器件构成,这些器件靠内部总线相连.
总线(地址,数据,控制)相对于CPU内部来说是外部总线.内部总线实现CPU内部各个组件之间的联系,外部总线实现CPU和主板上的联系.
- 运算器进行信息处理
- 寄存器进行信息存储
- 控制器控制各种器件进行工作
- 内部总线连接各种器件,在它们之间进行数据传送
CPU中主要的部件是寄存器,寄存器是CPU中程序猿可以用指令读写的部件.通过改变各种寄存器中的内容来实现对CPU的控制
不同的CPU,寄存器的个数,结构是不相同.8086CPU有14个寄存器,每个寄存器有一个名称.
寄存器
AX | BX | CX | DX | SI | DI | SP | BP | IP | CS | SS | DS | ES | PSW |
---|
通用寄存器
8086CPU的所有寄存器都是16位的,可以存放两个字节.
AX,BX,CX,DX
这4个寄存器通常用来存放一般的数据,被称为通用寄存器
一个16位的寄存器可以存储16位的数据,数据在寄存器
8086CPU的上一代CPU寄存器是8位的,为了兼容8086CPUAX,BX,CX,DX
这4个寄存器都可分为两个可独立使用的8位寄存器
寄存器 | 高位 | 低位 |
---|---|---|
AX | AH | AL |
BX | BH | BL |
CX | CH | CL |
DX | DH | CL |
16位数据寄存器存放情况
7CDE
放入AX
16位寄存器分为两个8位寄存器存放情况
AX的低8位(07)构成AL寄存器,高8位(815)构成AH寄存器.并且它们是独立的寄存器
字在寄存器中的存储
8086CPU可以一次性处理以下两种尺寸的数据
- 字节 byte: 一个字节由8bit组成,可以存放于8位寄存器中
- 字 word 一个字由两个字节组成,这两个字节分别称为这个字的高位字节和低位字节
一个字由两个字节组成
一个字可以存在16位寄存器中,它的高位字节和低位字节就存在于这个寄存器的高8位寄存器和低8位寄存器中.
十六进制的一位相当于二进制的四位,如0100 1110 0010 0000 可以表示为4(0100) E(1110) 2(0010) 0(0000)四位六进制数.
一个内存单元可以存放8位数据,CPU中的寄存器又可以存放n个8位数据,也就是说计算机中的数据大多数是由1~N个8位数据构成.
几条汇编指令
汇编指令 | 控制CPU完成的操作 | 用高级语言描述 |
---|---|---|
mov ax,18 | 将18送入寄存器AX | AX = 18 |
add ax,8 | 把AX寄存器中的数值加8 | AX = AX + 8 |
mov ax,bx | 将BX寄存器中的数据送入寄存器AX | AX = BX |
add ax,bx | 把AX和BX寄存器中的数值相加结果放入AX | AX = AX + BX |
检测点2.1
- 写出每条汇编指令之后相关寄存器中的值
汇编指令 | 结果 |
---|---|
mov ax,62627 | AX = F4A3 |
mov ax,31H | AX = 31A3 |
mov al,23H | AX=3123 |
add ax,ax | AX=6246 |
mov bx,826CH | AX=826C |
mov cx,ax | AX=6246 |
mov ax,bx | AX=826C |
add ax,bx | AX=04D8 |
mov al,bh | AX=82D8 |
mov ah,bl | AX=6CD8 |
add ah,ah | AX=D8D8 |
add al,6 | AX=D8DE |
add al,al | AX=D8DC |
mov ax,cx | AX=6246 |
- 只能用目前学过的知识,最多用4条汇编指令,计算出24次方
mov ax,2 = 2
add ax,ax = 4
add ax,ax = 8
add ax,ax = 10(16)
物理地址
CPU访问内存单元时,要给出内存单元的地址,所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,称为物理地址
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址,在CPU向地址总线发出物理地址之前,必须在内部先形成这个物理地址,不同的CPU可以有不同形成物理地址的方式.
16位结构的CPU
- 运算器一次最多可以处理16位的数据
- 寄存器最大宽度为16位
- 寄存器和运算器之间的通路为16位
8086CPU是16位结构的CPU,在内部能够一次性处理,传输,暂时存储的信息最大长度为16位.
内存单元的地址在送上地址总线之前,必须在CPU中处理,存储,暂时存放.对于16位CPU,能够一次性处理,传输,暂时存储16位的地址.
8086CPU给出物理地址的方法
8086CPU有20位地址总线,可以传送20位地址.达到1MB的寻址能力.
8086CPU又是16位结构,在内部一次性处理,传输,暂时存储的地址为16位.如果将地址从内部简单的发出,那么它只能送出16位的地址.寻址能力只有64KB.
- 8086采用一种在内部用两个16位地址合成的方法形成一个20位的物理地址.
当8086CPU要读写内存时
- CPU的相关部件提供两个16位地址,一个是
段地址
,另一个是偏移地址
. 段地址
和偏移地址
通过内部总线送入地址加法器
的部件- 地址加法器将两个16位地址合成为一个20位的物理地址.
- 地址加法器内部总线将20位物理地址送入输入输出控制电路.
- 输入输出控制电路将20位物理地址送上地址总线
- 20位物理地址被地址总线传送到存储器
地址加法器采用
物理地址=段地址x16+偏移地址
的方法用段地址和偏移地址合成物理地址.
假如 8086CPU要访问地址为123C8的内存单元.
地址加法器的工作流程如下
段地址x16 常用的说法是
左移4位
,左移4位
指的是二进制位
左移运算例子,一个数据为2H,二进制就是10B.
左移位数 | 二进制 | 十六进制 | 十进制 |
---|---|---|---|
0 | 10B | 2H | 2 |
1 | 100B | 4H | 4 |
2 | 1000B | 8H | 8 |
3 | 10000B | 10H | 16 |
4 | 100000B | 20H | 32 |
- 一个数据的二进制左移1位,相当于该数据乘以2
- 一个数据的二进制左移N位,相当于该数据乘以2的N次方
- 段地址x16的运算就是将以二进制形式存放的段地址左移4位
0001 0010 0011 0000 => 0001 0010 0011 0000 0000
段地址x16+偏移地址=物理地址的本质含义
本质含义:CPU在访问内存单元时,用一个基础地址(段地址x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址
比如学校,体育馆,图书馆在一条笔直的单行路上
你要去图书馆,问我那里的地址,有两种图书馆地址
- 从学校走2826米到图书馆
- 从学校走2000米到体育馆,从体育馆再走826米到图书馆
第一种是直接给出物理地址2826米
第二种方式是用基础地址和偏移地址相加来得到物理地址
如果我们加一点限制条件,比如只能通过纸条来通信,你问我图书馆地址我只能将它写在纸上.
我必须要有一张容纳4位数据的纸条,才能写下2826的数据.
2 | 8 | 2 | 6 |
---|
如果我没有4位纸条,仅有2张可以容纳3位数据的纸条,只能用这种方式告诉你2826这个数据
2 | 0 | 0 |
---|
8 | 2 | 6 |
---|
在第一张纸上写上200(段地址),再在第二种纸上写上826(偏移地址),你得到两张纸后做这样的运算200(段地址)x10+826(偏移地址)=2826(物理地址)
段的概念
内存并没有分段,段的划分来自CPU,8086CPU用基础地址(段地址x16)+偏移地址=物理地址
的方式给出内存单元的物理地址.使得我们可以用分段来管理内存。
比如:
- 地址10000H~100FFH的内存单元组成一个段,该段的起始基础地址为10000H,段地址1000H(基础地址
右移4位
),大小100H((100FF - 10000)+1)
将若干个地址连续的内存单元看作一个段,用段地址x16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元.
段地址x16必然是16的倍数,所以一个段的起始地址也一定是16的倍数.偏移地址为16位,16位的寻址能力为64KB,所以这个段的长度最大为64KB.
CPU可以用不同的段地址和偏移地址形成同一个基础地址.
比如CPU要访问21F60单元,则它给出的段地址SA和偏移地址EA满足(SA x 16) + EA = 21F60
SA(21F6) = 21F60 >> 4 --右移4位
段地址范围 = 11F7 ~ 21F6
偏移地址范围 = 0 ~ FFFF
21F60 ~ 31F5F --CPU寻址范围 (SA << 4) + FFFF = 最大范围
大小: (31F5F - 21F60) + 1 = 10000H
检测点
- 给定段地址为0001H,仅通过变化偏移地址寻址,CPU寻址范围为
10~1000F
- 有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻找此单元,则SA应满足的条件是最小
1001
,最大2000
段寄存器
8086寄存器有4个段寄存器,当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址.
CS | DS | SS | ES |
---|
CS和IP
CS 和 IP 是8086CPU中两个最关键的寄存器,它们指示了CPU当前要读取指令的地址.
- CS为代码段寄存器
- IP为指令指针寄存器
8086CPU 任意时刻,设置CS中的内容为M,IP中的内容为N,8086CPU将从内存M x 16 + n
单元开始,读取一条指令并执行
CPU将CS:IP指向的内容当作指令执行