汇编语言基础
基础知识
指令系统
复杂指令集(CISC
):Intel系、VAX
精简指令集(RISC
):ARM、MIPS、PowerPC、SPARC、RISC-V
指令集架构
X86
:美国intel(CISC)
,桌面端ARM
:英国arm(RISC)
,移动端LoongArch
:龙芯
语言 | 特点 | 优点 | 缺点 |
---|---|---|---|
机器语言 | 二进制代码,机器指令的集合,称为机器码,CPU可直接解读 | 执行速度快,效率高 | 表意不直观,读、写、改较困难 |
汇编语言 | 符号语言,与机器语言一一对应,主体是汇编指令,是机器指令便于记忆的书写格式(机器指令的助记符) | 面向硬件编程,时空上效率较高 | 涉及硬件细节,需要熟悉计算机系统内部结构 |
高级语言 | 面向人的语言,表示形式接近自然语言 | 易学易用 | 代码冗长,占用内存多,执行时间长,效率不高,不能操作某些硬件 |
why assembly?
- 汇编语言在CPU的寄存器级上进行控制和操作,直接对计算机硬件进行编程
- 在计算机系统中,机器自检、系统初始化、实际输入输出设备的操作等都需要用汇编语言程序实现
程序员 — 汇编指令(.asm
)—> 汇编器 — 机器码
—> 计算机执行
汇编语言组成:
- 汇编指令(核心)
- 伪指令
- 其他符号
数制和码
进制转换
十进制、二进制、十六进制的整数、小数转换
补码运算
原码、反码、补码的运算
有符号数及符号位扩展
无符号数和有符号数
符号位扩展:将字节扩展为字,字扩展到双字
编码
BCD码
BCD码用于计算人熟知的十进制数,在二进制的BCD码中,十进制的0-9
都有与之对应的二进制码
- 8位的二进制数可以表示16个不同的数,于是有不同的方案省去那多余的6个表示
- 相应在计算时,若碰到
11-15
这样多余的数,要进行相应处理:加6修正(若是高位则为加60H
)
8421码:就是用二进制数表示十进制数中的0-9
,一一对应
余3码:在8421码的基础山,每个十进制数对应的二进制数+3,是为“余3”
2421码:0-4
五个数对应二进制的0-4
,5-9
五个数对应二进制的11-15
,中间空出6个二进制数
十进制数 | 8421码 | 2421码 | 余3码 |
---|---|---|---|
0 | 0000 | 0000 | 0011 |
1 | 0001 | 0001 | 0100 |
2 | 0010 | 0010 | 0101 |
3 | 0011 | 0011 | 0110 |
4 | 0100 | 0100 | 0111 |
5 | 0101 | 1011 | 1000 |
6 | 0110 | 1100 | 1001 |
7 | 0111 | 1101 | 1010 |
8 | 1000 | 1110 | 1011 |
9 | 1001 | 1111 | 1100 |
压缩的BCD码:用1一个字节(8位)二进制数表示两个8421码
364D = 00000011 01100100(BCD) = 0364H
非压缩的BCD码:1一个字节(8位)二进制数只表示一个8421码
364D = 00000011 00000110 00000100(BCD) = 030604H
十进制数运算:BCD码作十进制运算,低4位若大于9,则要加6
调整,高四位同理,需加60H
调整,手动进位
可靠性编码
8421奇偶校验码
ASCII码
常用代码 | ASCII对照 |
---|---|
大写字母A-Z | 41H-5AH |
小写字母a-z | 61H-7AH |
数字0-9 | 30H-39H |
空格 | 20H |
回车 | 0DH |
换行 | 0AH |
响铃 | 07H |
计算机基本原理
微型计算机系统
微机结构
微型计算机指的就是个人计算机
硬件结构:CPU、电源、内存、光驱、光驱数据线、软驱、硬盘、主板、显卡......
主板:独立显卡、SATA
口、USB
接口、IDE
口、主板供电电源24pin
微机结构:中央处理器、输入设备、内存储器、输出设备
C_BUS, D_BUS, A_BUS
等总线连接各个设备
冯诺依曼计算机
冯诺依曼计算机基本结构:CPU、存储器、输入输出设备、总线及接口
CPU组成:算术和逻辑运算单元ALU、地址发生和控制单元、指令译码单元、数据寄存器单元、总线驱动单元、时序控制单元等
存储器:一般指内存
- 内存:ROM(缓存)、RAM(内存条)
- 外存:硬盘
输入输出设备:统称位外部设备,用于实现人机交换
总线及接口
计算机总线
内部总线:链接CPU内部各个部件
外部总线:又称系统总线,连接计算机主板上各种芯片以及各个接口部件
分为地址总线、数据总线和控制总线三大类
接口:外部设备和计算机主机之间作为缓冲部件的中间介质
- 并行接口:同时并行传输多位数据
- 串行接口:一位接一位传输
冯诺依曼计算机特点:
- 程序和数据放在同一个存储器中,两者都可以送到CPU执行
- 存储器按地址访问
- 指令由操作码和地址码构成,实现存取
- 以运算器为中心,输入输出设备都要经过CPU和存储器进行数据传送
微处理器
微处理器:分为执行部件EU
和总线接口部件BIU
EU
(execution unit)
- 运算器的算术逻辑运算单元ALU
- 通用寄存器组
- 标志寄存器FLAGS
- EC单元控制系统等
BIU
(Bus Interface Unit)
- 段寄存器组:
CS、DS、ES、SS
- 指令指针寄存器
IP
- 指令队列单元
- 地址加法器
- 总线控制系统等
80X86寄存器
Register
8086寄存器组
intel8086、80286都是16位的寄存器,从80386开始寄存器扩展为32位
数据寄存器:AX,BX,CX,DX
地址寄存器:SI,DI;SP,BP
段寄存器:CS,DS,ES,SS
控制寄存器:IP;FLAGS
数据寄存器
包括AX,BX,CX,DX
四个16位通用寄存器
AX(accumulator)
:作为累加器用,算术运算的主要寄存器
BX(base)
:基址寄存器
CX(count)
:计数器
DX(data)
:双精度运算时与AX一起存放双操作数
当存放双操作数时,AX
存放低字,DX
存放高字,在AX
中,AH
存放高位,AL
存放低位,DX
同理,DH
存放高位,DL
存放低位
地址寄存器
地址寄存器包括指针和变址寄存器(SI,DI,SP,BP
),用于存放存储器的偏移地址
- 也可以用作通用寄存器
- 严格来说,用来存放存储器偏移地址的寄存器都应该叫地址寄存器,如BX基址寄存器、IP指令指针寄存器等
SI(Source Index)
:源变址寄存器,用于存放源缓冲区的偏移地址
DI(Destination Index)
:目的变址寄存器,用于存放目的缓冲区的偏移地址
SP(Stack Pointer)
:堆栈指针寄存器,用于指出堆栈区栈顶的偏移地址
BP(Base Pointer)
:基址指针寄存器,用于指出堆栈区某个单元的偏移地址
段寄存器
CS(Code Segment)
:代码段寄存器
DS(Data Segment)
:数据段寄存器
ES(Extra Segment)
:附加段寄存器
SS(Stack Segment)
:堆栈段寄存器
控制寄存器
IP(Instruction Pointer)
:指令指针寄存器,用来存放代码段中的偏移地址,指出当前正在执行指令的下一条指令所在单元的偏移地址
FLAGS
:标志寄存器,其中某位代表CPU的一个标志,表示CPU的某种执行状态
- 作用:作为加减运算和逻辑运算的辅助结果;构成各种条件,实现程序分支
标志寄存器
最低为:D0
最高位:D15
共有9个标志,分别为6个条件码标志和3个控制标志
标志位 | 标志 | 值为1 | 值为0 |
---|---|---|---|
进位标志 | CF(carry flag) | CY | CN |
进位标志 | SF(symbol flag) | NG | PL |
零标志 | ZF(zero flag) | ZR | NZ |
溢出标志 | OF(overflow flag) | OV | NV |
辅助进位标志 | AF(assistant flag) | AC | NA |
奇偶标志 | PF(parity flag) | PE | PO |
方向标志 | DF(direction flag) | DN | UP |
中断标志 | IF(interrupt flag) | EI | DI |
陷阱标志 | TF |
溢出:两带符号二进制数相加,负负加为正,正正加为负,这样的情况称为溢出
OF=1
- 处理器在判断时其实判断的是最高位和次高位是否同时进位。若同时进位则溢出
内存储器
简称内存
存储器被分为若干存储单元,从0开始编号
- 如一个存储器有128个存储单元,则编号从0~127
存储单元
存储单元分为
- 字节单元(8位)
- 字单元(16位)
- 双字单元(32位)
在存储器中进行表示时
(3075AH) = 12H
:3075AH
号单元中的内容是12H
(307692H) = 5678H
:表示307692,307693
两个单元一起存放5678H
在存放时,高字节放在高地质单元,低字节放在低地址单元
存储单元容量
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
CPU对存储器的读写
CPU进行数据读写需要和芯片进行三类信息的交互
- 地址信息:存储单元的地址
- 控制信息:器件的选择,读或写命令
- 数据信息:读写的数据
CPU和芯片的交互用导线传输:称为总线
逻辑上划分为
地址总线:CPU通过地址总线指定存储单元,地址总线上传输的信息数为CPU能够寻址的存储单元数
若有N根地址总线,则可寻找2^N个存储单元
数据总线
数据总线的宽度决定了CPU和外界数据的传输速度
控制总线
读信号输出控制线负责由CPU向外传送读信号
写信号输出控制线负责由CPU向外传送写信号
物理地址和逻辑地址
Address
地址
在80x86
系统中一个存储单元只存放8位二进制数,称为字节单元
一根地址线可以传输两种信号,即0/1
两根地址线可以传输四种信号,00,01,10,11
以此类推,n根地址线可以传输2^n个信号,也就是说可以传输2^n个存储单元地址
物理地址
内存单元的真实地址,存储单元的物理地址是唯一的
8086CPU
有20根地址线,因此其存储空间可达2^20字节单元,采用十六进制表示的物理地址范围是00000H~FFFFFH
逻辑地址
用户编程时使用的地址,分为段地址和偏移地址两部分
在8086
汇编语言中,把内存地址空间划分为若干逻辑段,每段由一些存储单元构成
- 段地址和偏移地址都是十六位二进制数
- 逻辑地址形式:
段地址:偏移地址
逻辑地址与物理地址的转换
物理地址 = 段地址x10H+偏移地址
存储器分段
分段的概念
8086CPU
的地址寄存器只有16位。如果直接从地址寄存器中发出地址信号,所能访问的存储空间只有2^16=64k,达不到20位地址线所提供的地址范围
将存储器划分为若干逻辑段,每段最多64k
字节单元
- 逻辑段大小可变,最少16个字节单元,最大65536个字节单元
段地址和偏移地址构成逻辑地址:[段地址]:[偏移地址]
在存储器中,规定每16个字节单元为一小段,小段的第一个单元的物理地址为小段的首地址
- 首地址的特点是十六进制表示的物理地址的最低位都是0(段地址x10,末位必为0)
- 末单元的最低位都是F(每段16位,从0开始)
- 所以我们将首地址除以10,记为逻辑地址,这样就可以用16位寄存器进行存储,即保存有意义的高四位16进制数
段的类型
逻辑段分为四类
- 代码段:
CS:IP
- 数据段:
DS:BX/SI/DI
- 附加段:
ES:BX/SI/DI
- 堆栈段:
SS:SP/BP
上述为物理地址的表示方式:[段地址寄存器]:[偏移地址寄存器]
堆栈
LIFO:Last In First Out
先进先出的原则,上子弹和下子弹的过程
进入计算机
调试工具DEBUG
DEBUG命令
DEBUG命令 | 作用 |
---|---|
R | 查看和修改寄存器 |
D | 查看内存单元 |
E | 修改内存单元 |
U | 反汇编 |
T | 单步执行 |
G | 连续执行命令,跳转 |
A | 输入汇编指令 |
Q | 推出 |
进入DOS
DOS命令 | 作用 |
---|---|
cd\ | 返回根目录 |
dir | 显示文件列表 |
cd dir | 进入文件夹dir |
cd .. | 返回上一目录 |
e: | 进入e盘 |
cls | 清屏 |
进入DEBUG
R命令:
- 直接键入,将显示CPU所有寄存器和标志位
- R后跟写寄存器名,将先显示寄存器内容,在冒号后可键入新的值
E命令:
- 格式:E 起始地址 修改值 修改值 ……
- 可以一次改写多个存储单元的内容
指令系统和寻址方式
汇编语言指令
机器指令
也称作代码指令,是计算机能识别的一组二进制代码
将数7送到AL中
1011 0000 0000 0111B
B007H
2
把数3与AL相加放在AL中
0000 0100 0000 0011B
0403H
2
把AL中的内容送到地址为5的存储单元中
1010 0010 0101 0000 0000 0000B
A25000H
2
汇编指令
上述三个命令简化为
mov al,7
add al,3
mov ds:[5],al
2
3
实际上就是一个代码到机器码的映射
指令格式
汇编指令由操作码字段和操作数字段构成
- 操作码字段:类英文单词的助记符,知名操作数的性质
- 操作数字段:被操作的数据的值或数据的位置
指令根据操作数个数分为
单操作数指令,如
inc ax
push ax
jmp let
双操作数指令,如
mov ax,7
add ax,bx
三操作数指令(
80386
指令):imul ebx,[esi],7
无操作数指令,如
cbw:字节转换为字指令
hlt:停机
aaa:加法进位
aam:乘法进位
指令属性
指令长度:分为单字节、双字节、三字节、四字节和多字节指令等
指令执行时间,以CPU时钟周期为单位
指令系统
指令系统指计算机所能执行的各种代码指令的集合
指令分类
- 数据传送指令
- 算术运算指令
- 逻辑运算指令
- 字符串处理指令
- 控制与转移指令
- 处理机控制指令
指令的存取
通过CS
和IP
寄存器来存取指令:[cs]:[ip]
CS
代码段寄存器存放代码的段地址
IP
指令指针寄存器存放代码的偏移地址
取指过程
- 从
CS:IP
指向内存单元读取指令,进入指令缓冲区 IP = IP+当前读取指令长度
,指向下一条指令- 执行指令,转到1,重复步骤
指令的寻址方式
立即寻址方式
操作数直接写在指令中,这样的操作数也被称为立即数
mov ax,3060H
mov al,5
mov bl,0FFH
mov bx,0A46DH
mov ch,23
mov dx,55H
2
3
4
5
6
寄存器寻址方式
操作数在寄存器中,指令中指定寄存器名
八位寄存器:AH,AL,BH,BL,CH,CL,DH,CL
十六位寄存器:AX,BX,CX,DX,SI,DI,BP,SP
mov ax,bx
add bx,2233H ;目的操作数是寄存器寻址
2
存储器寻址方式
操作数放在内存中,通过段地址+有效地址的形式寻址从内存中取出操作数
直接寻址方式
将操作数的有效地址直接写在指令中
- 适用于处理单个变量
mov ax,ds:[2000H]
mov ds:[4000H],ax
2
其中2000H
为有效地址(偏移地址),即从ds
段后2000H
的地方取出操作数
写操作同理
直接寻址还可以使用符号地址的形式,即为存储单元的偏移地址定义成一个名字(符号地址)
value equ 1000H
mov ax, value
mov ax, [value]
2
3
若DS=1500H
,则物理地址 = DS*10H+EA = 15000H+1000H = 16000H
,计算机从内存存储单元编号为16000H
的位置取出操作数
寄存器间接寻址方式
有效地址用寄存器存储,同样是通过段地址:偏移地址
的形式寻址
- 适用于简单的表格处理
mov ax,[bx]
mov ax,[bp]
mov SS:[DI],AX
2
3
这里的偏移地址有默认的段地址,所以可以省略
寄存器BX,SI,DI
默认的段寄存器为DS
寄存器BP
默认的段寄存器为SS
这四个寄存器BX,SI,DI,BP
也被称为间址寄存器
寄存器相对寻址方式
综合了直接寻址和间接寻址,即同时用寄存器和立即数存储偏移地址
- 用于查表操作
这五条指令取得都是同一个操作数,位置在DS:BX+1234H
top equ 1234H
mov ax,top[bx]
mov ax,[bx+top]
mov ax,[bx+1234H]
mov ax,[bx].1234H
mov ax,1234H[bx]
2
3
4
5
6
基址变址寻址方式
用两个寄存器来存储操作数的偏移地址
- 用于二维表的处理
mov ax,[bx+di]
mov ax,[ax][di]
mov [bp+si],ax
mov [bp][si],ax
2
3
4
5
上下二者均等效,找的物理地址分别为
DS*10H + BX + DI
SS*10H + BP + SI
相对基址变址寻址方式
通过两个寄存器+一个立即数来存储偏移地址
下列三条命令均等效
value equ 1234H
mov ax,[bx+si+1234h]
mov ax,[bx][si].value
mov ax,1234h[bx+si]
2
3
4
物理地址在基址变址寻址的基础上多加一个立即数