汇编语言基础
# 基础知识
# 指令系统
复杂指令集(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 = 1024B1MB = 1024KB1GB = 1024MB1TB = 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 + DISS*10H + BP + SI
# 相对基址变址寻址方式
通过两个寄存器+一个立即数来存储偏移地址
下列三条命令均等效
value equ 1234H
mov ax,[bx+si+1234h]
mov ax,[bx][si].value
mov ax,1234h[bx+si]
2
3
4
物理地址在基址变址寻址的基础上多加一个立即数