1 汇编语言与机器语言
人与计算机交流的语言,需要让计算机做事
人——》汇编语言——》编译器——》机器语言——》计算机
2 进制
逢几进几的运算,不同进制只是表示方法不同,对应同一个数字。意义相同。
3 存储器,CPU
存储器:存储数据,提供数据
- 外部存储器:硬盘,光盘
- 内部存储器:RAM(内存条),ROM(BIOS芯片)
- 一个存储单元存储一个字节
CPU:中央处理器
- 运算器:数据进行计算
- 控制器:控制操作步骤
CPU对存储器的读写
- 通过三根总线读写:地址总线,数据总线,控制总线
- 地址总线——》寻址能力(80386为32根)
- 数据总线——》一次数据传输量(80386为32根)
- 控制总线——》对其他器件的控制能力
4 寄存器
寄存器是CPU内部的组成部分,可以用来暂存指令,数据,地址
-
8086有14个寄存器,16位,一个字
4个数据寄存器:AX,BX,CX,DX
2个变址寄存器:SI,DI
2个指针寄存器:SP,BP
4个段寄存器:ES,CS,SS,DS
1个指令指针寄存器:IP
1个标志寄存器:Flags
-
80386有16个寄存器,32位,两个字
4个数据寄存器:EAX,EBX,ECX,EDX
2个变址寄存器:ESI,EDI
2个指针寄存器:ESP,EBP
6个段寄存器:ES,CS,SS,DS,FS,GS
1个指令指针寄存器:EIP
1个标志寄存器:EFlags
32位的通用寄存器通用性更强一些,数据寄存器也可以为指令寄存器
5 简单的汇编指令
mov ax ,11F6H
add al , 0AH
最后ax的值为1100H
6 CS:IP
程序运行时,将代码段加载到内存中,然后CPU在内存中找到代码段,也就是代码的物理地址执行。
物理地址=基础地址+偏移地址
=段地址 x 10H + 偏移地址
修改CS:IP可以达到控制程序执行的目的,有两种方法:
-
同时修改CS:IP的内容
jmp 段地址:偏移地址
jmp 2AE3:3 ——》从2AE33H处读取指令
jmp 3:0B16——》从00B46H处读取指令
-
修改IP 的内容
jmp 寄存器
jmp bx 含义上与 mov IP,bx 相同,因为执行前后的变化为
bx cs ip 0x0B16H 0X2000H 0x0003H 执行前 0x0B16H 0X2000H 0x0B16H 执行后
7 debug使用
7.1 环境配置
winxp可以直接使用debug,其他的环境需要使用DOSBox+debug.exe。
下载安装,然后在安装目录中找到DOSBox 0.74 Option.bat,打开之后,找到autoexec选项,添加如下字段:
MOUNT C D:\masmpro
set PATH=$PATH$;D:\xxxxx
并且在d盘下创建xxxxx目录,并且放入:debug.exe,edit.com,LINK.EXE,MASM.EXE
7.2 常用操作
- R:查看更改CPU中,寄存器的值
- D:查看内存中的内容
- E:改写内存中的内容
- U:将内存中的机器指令翻译为汇编指令
- T:执行一条机器指令
- A:以汇编的格式在内存中写入一条指令
8 分段管理
物理地址是内存单元的编号。
逻辑地址是用户编程时使用的,形式为(段基址:段内偏移地址),物理地址=段基址x10H+偏移地址
8086CPU有4个段寄存器,用来确定每个逻辑段的起始位置,各个段寄存器含义如下:
- CS(代码段):指明代码的起始地址,使用方式(CS:IP)
- SS (堆栈段):指明堆栈段的起始地址,使用方式(SS:SP)
- DS(数据段):指明数据的起始地址,使用方式(DS:EA)
- ES(附加段):指明附加段的起始地址,使用方式(ES:EA)
9 标志寄存器
8086的标志位寄存器如下
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OF | DF | IF | TF | SF | ZF | AF | PF | CF |
-
状态标志:
用于记录运行结果的状态信息:CF,ZF,SF,PF,OF,AF
-
控制标志:
用于控制处理器执行指令:DF,IF,TF
寄存器 意义 举例 CF 进位标志,有进位时flag=1 c2H+c7H=(1)89H,标志位为1 ZF 零标志位,运算结果为0,flag=1 39H+c7H=(1)00H,标志位为1 SF 符号标志位,最高位为1,flag=1 2CH+7CH=A8H,标志位为1 PF 奇偶标志位,字节中1的个数为偶数,flag=1 39H+C7H=(1)00H,标志位为1 OF 溢出标志,运算有溢出,OF=1 2CH+7CH=A8H,标志位为1 AF 辅助进位标志,低半字节有进位或借位,flag=1 39H+78H=B1H,标志位为1 DF 方向标志位,用于串操作中控制地址方向,存储器地址自动减少,flag=1 CLD执行后DF=0;STD执行后DF=1 IF 中断标志位,中断是否可以被响应,flag=1,允许中断 CLI指令用于复位中断标志,IF=0。STL用于置位,IF=1 TF 陷阱标志位,控制处理器单步操作的方式。flag=1,单步执行 单步执行指令,可以对程序进行调试
10 指令
指令一般由:操作码+操作数。构成
根据操作数的类型不同,指令的结构可以为:操作码+目的操作数+源操作数
11 寻址方式
指令中数据的存储位置有3种
- 存放在指令中(立即数)
- 存于寄存器中(寄存器操作数)
- 存于存储器中(存储器寻址)
寻址方式
寻址方式 | 例子 | 解释 |
---|---|---|
立即数寻址 | mov al,80H | 源操作数是数据,目的操作数是寄存器 |
寄存器寻址 | mov ax,cx | 将寄存器中的值赋给另一个寄存器 |
直接寻址 | mov al,[1064H] | 操作数存在内存中,操作数的偏移地址直接在指令中,默认操作数在数据段 |
寄存器间接寻址 | mov ax,[si]####mov [bx],al | bx,si,di作为间接寻址寄存器,默认操作数存放于数据段,段寄存器使用DS。bp作为间接寻址寄存器,默认操作数存放于堆栈段,段寄存器使用ss |
寄存器相对寻址 | mov cl,[bx+1064H] | 相对于寄存器间接寻址多了一个偏移量 |
基址加变址寻址方式 | mov ah,[bp] [si] | bx,bp是基址寄存器,把si和di变址寄存器,计算时,段寄存器+bp的值+si的值 |
相对基址加变址寻址方式 | mov [bx+di+1234H],ah | 比基址加变址寻址方式多了一个偏移量 |
12 汇编指令
12.1 数据传送指令
12.1.1 通用传送指令
指令 | 格式 | 其他 |
---|---|---|
mov | mov dst,src | 1.存储器操作数之间不能直接传送:mov [1000H],[di]错误,应使用通用寄存器 |
2.立即数不能直接送段寄存器: mov ds,1000H | ||
3.段寄存器之间不能直接传递: mov es,ds | ||
4.cs只可以作为源操作数: mov cs ,ax | ||
5.源操作数和目的操作数位数需要相同 | ||
push | push src | sp-2(因为按一个字两个字节为单位操作),然后按“高高低低原则”放入数据 |
pop | pop dst | 现弹出数据,然后sp-2 |
xchg | xchg dst,src |
12.1.2 累加器专用传送指令
指令 | 格式 | 说明 |
---|---|---|
IN (用于CPU从外设端口中接收数据) | IN AL,data8 | 8位端口输入一字节 |
IN AX,data8 | 8位端口输入一字 | |
IN AL,DX | 16位端口输入一字节 | |
IN AX,DX | 16位端口输入一字 | |
OUT (用于CPU向外设端口中发送数据) | OUT data8,AL | 给8位端口输出一个字节 |
OUT data8,AX | 给8位端口输出一个字 | |
OUT DX,AL | 给16位端口输出一个字节 | |
OUT DX,AX | 给16位端口输出一个字 | |
LEA(将源操作数的偏移地址传送到目的操作数) | LEA reg16,mem | 目的操作数必须是16位的寄存器, |
LDS(将源操作数指定的4个相继字节的数据分别送指令到指定的寄存器及DS寄存器) | LES reg16 ,mem | 先给寄存器赋值,然后,从内存中读取两个字节 |
12.1.3 地址传送指令
指令 | 格式 | 说明 |
---|---|---|
LEA(将源操作数的偏移地址传送到目的操作数) | LEA reg16,mem | 目的操作数必须是16位的寄存器, |
LDS(将源操作数指定的4个相继字节的数据分别送指令到指定的寄存器及DS寄存器) | LES reg16 ,mem | 先给寄存器赋值,然后,从内存中读取两个字节 |
12.1.4 标志传送指令
指令 | 格式 | 说明 |
---|---|---|
LAHF(标志寄存器的低八位赋值给AH) | LAHF | psw的低字节——》AH |
SAHF(AH的值赋值给标志寄存器) | SAHF | AH——》psw的低字节 |
PUSHF | PUSHF | (SP)《——(SP)-2 |
((SP)+1,(SP))《——(PSW) | ||
POPF | POPF | (PSW)《——((SP)+1,(SP)) |
(SP)《——(SP)+2 |
12.2 算术运算类指令
加减乘除
12.2.1 加法指令
指令 | 格式 | 描述 |
---|---|---|
add(加法指令) | add dest,src | (dest)《——(dest)+(src) |
adc(带进位的加法) | adc dest,src | (dest)《——(dest)+(src)+C(进位标志) |
inc(自增一) | inc | (dest)《——(dest)+1 |
aaa(加法ascii调整指令) | ||
daa(加法十进制调整指令) |
12.2.2 减法指令
指令 | 格式 | 描述 |
---|---|---|
sub (减法指令) | sub dest,src | (dest)《——(dest)-(src) |
sbb(带进位的减法指令) | sub dest,src | (dest)《——(dest)-(src)- C |
dec(自减1指令) | dec | (dest)《——(dest)-1 |
neg(求补指令) | neg dest | (dest)《—— 0 -(dest) |
cmp(比较指令) | cmp dest,src | 不影响结果,只改变标志位 |
12.2.3 乘法指令
指令 | 格式 | 描述 |
---|---|---|
mul(无符号乘法) | mul src | 1.字节操作数:ax《——(al)*(src) |
2.字操作数:dx:ax《——(ax)*(src) | ||
imul(带符号乘法) | imul src |
12.2.4 除法指令
指令 | 格式 | 描述 |
---|---|---|
div(除法) | div src | 1.字节除数:al《——(ax)/(src)之商 |
ah《——(ax)/(src)之余数 | ||
2.字除数:ax《——(dx:ax)/(src)之商 | ||
dx《——(dx:ax)/src 之余数 | ||
idiv(带符号除法) | idiv src |
12.2.5 字节扩展指令
指令 | 格式 | 描述 |
---|---|---|
cbw | cbw | 将al扩展为字,符号位和高字节在ah中,对被除数进行扩充 |
12.2.6 字扩展指令
指令 | 格式 | 描述 |
---|---|---|
cwd | cwd | 将ax扩展为双字,符号位和高字在dx中,对被除数进行扩充 |
12.3 位操作类
12.3.1 逻辑运算指令
指令 | 格式 | 描述 |
---|---|---|
and | and dest ,src | (dest)《——(dest)^(src) |
test | test dest,src | (dest)^(src) |
or | or dest ,src | (dest)《——(dest)||(src) |
xor | xor dest ,src | 不同为1,相同为0 |
not | not dest | 按位取反 |
12.3.2 移位指令
以下指令格式均为:操作码 寄存器/内存 ,数字
指令 | 描述 |
---|---|
sal(算术左移) | 相当于无符号数乘2,末尾补0 |
sar(算术右移) | 最高位不变,最低位移入CF |
shl(逻辑左移) | 相当于无符号数乘2,末尾补0 |
shr(逻辑右移) | 相当于无符号数除以2,高位补0,地位进入CF |
rol(不含进位标志循环左移) | 高位的数放到低位,同时放入CF中 |
ror(不含进位标志循环右移) | 低位的数放到高位,同时放入CF中 |
rcl(带进位循环左移) | 将原先的CF存入低位,左移后的高位放入CF |
rcr(带进位循环右移) | 将原先的CF存入高位,右移后的低位放入CF |
12.4 串操作指令
串操作,也叫数据块操作。串是内存中一段相连的字节或字,可以实现存储器数据块之间的直接传送。
指令 | 格式 | 描述 |
---|---|---|
movs(串传送指令) | movsb | (ES:DI)《——(DS:SI) |
(SI)《——(SI)+/- 1 | ||
(DI)《——(DI)+/- 1 | ||
movsw | (ES:DI)《——(DS:SI) | |
(SI)《——(SI)+/- 2 | ||
(DI)《——(DI)+/- 2 |
mov ax,1000H
mov ds,ax;数据段地址赋值
mov ax,1000H
mov es,ax;附加段赋值
mov si,0013H;源数据块首地址
mov di,1004H;目的数据块首地址
mov cx,4;数据块长度赋计数器
std
lp:
movsb;完成一个字节的数据传送
dec cx;计数器减一
jnz lp;结果不为0,重复传送
hlt
lpwithoutmovsb:
mov ax,[si]
mov es:di,ax
dec si
dec di
dec cx
jnz lpwithoutmovsb
lpuserep:
rep movsb
hlt
指令 | 格式 | 描述 |
---|---|---|
lods(串中取数指令) | lodsb | (AL)《——(DS:SI) |
(SI)《——(SI)+/- 1 | ||
lodsw | (AX)《——(DS:SI) | |
(SI)《——(SI)+/- 2 | ||
stos(存入串指令) | stosb | (ES:DI)《——(AL) |
(DI)《——(DI)+/- 1 | ||
stosw | (ES:DI)《——(AX) | |
(DI)《——(DI)+/- 2 | ||
cmp(比较指令) | cmpsb | (ES:DI)《——(DS:SI) |
(SI)《——(SI)+/- 1 | ||
(DI)《——(DI)+/- 1 | ||
smpsw | (ES:DI)《——(DS:SI) | |
(SI)《——(SI)+/- 2 | ||
(DI)《——(DI)+/- 2 | ||
scas(串扫描指令) | scasb | (AL)-(ES:DI) |
(DI)《——(DI)+/-1 | ||
scasw | (AX)-(ES:DI) | |
(DI)《——(DI)+/-2 |
;cmps和scas可与前缀repe/repz/repne/repnz联合工作
;repe 相等时重复操作
;repz 为0时重复操作
;repne 不相等时重复操作
;repnz 不为0时重复操作
mov edi,s1
mov esi,s2
mov ecx,0xFFFFFFFF
xor eax,eax;先清空eax
repne scasb;等到eax=0时,停止接收数据
not ecx;计算得到的字符串长度
mov edi,s1
mov esi,s2
xor edx,edx
repe cmpsb;不相等则退出
12.5 程序控制指令
12.5.1 转移指令
控制程序从一处转向另一处执行,目标地址赋值给CS:IP实现
12.5.1.1 根据标志位判断转移
指令 | 格式 | 描述 |
---|---|---|
jmp(强制跳转) | jmp xx | 无条件跳转 |
jz/jnz(根据z标志位判断跳转) | ||
jc/jnc(根据c标志位判断跳转) | ||
jp(jpe)/ jnp(jpo)(根据p标志位判断跳转) | ||
js/jns(根据s标志位判断跳转) | ||
jo/jno(根据o标志位判断跳转) |
12.5.1.2 根据两个无符号数的大小判断转移
指令 | 格式 | 描述 |
---|---|---|
jb(低于跳转) | ||
jbe(不高于跳转) | ||
ja(高于跳转) |
12.5.1.3 根据两个带符号数的大小判断
指令 | 格式 | 描述 |
---|---|---|
jl(jnge)/jnl(jge)(小于跳转/不小于跳转) | ||
jle(jng)/jnle(jg) |
12.5.2 过程(子过程)调用指令
子程序——程序中具有独立功能的部分编写成独立程序模块
指令 | 格式 | 描述 |
---|---|---|
call 子过程名 | ||
ret | 返回主程序 |
12.5.3 循环控制指令
指令 | 格式 | 描述 |
---|---|---|
loop(无条件循环) | loop Lable | (CX)《——(CX)-1 |
CX 不等于0,转向Lable;CX=0,执行loop后面的语句 | ||
loopz/loope(有条件跳转) | loopz/loope Lable | (CX)《——(CX)-1 |
CX 不等于0,并且ZF=1,转向Lable;否则,执行loop后面的语句 | ||
loopnz/loopne(有条件跳转) | loopnz/loopne Lable | (CX)《——(CX)-1 |
CX 不等于0,并且ZF=0,转向Lable;否则,执行loop后面的语句 |
12.5.4 中断指令
指令 | 格式 | 描述 |
---|---|---|
中断调用 | int n | n的范围为0-255 |
中断返回 | iret |
12.6 处理器控制指令
12.6.1 标志处理指令
指令 | 描述 |
---|---|
clc | 清c标志 |
stc | 置c标志 |
cmc | 对c求反 |
cld | 清d标志 |
std | 置d标志 |
cli | 清i标志 |
sti | 置i标志 |
12.6.2 其他处理机控制机制
指令 | 描述 |
---|---|
nop | 空操作 |
hlt | cpu暂停状态 |
wait | cpu等待状态 |
esc | 交权 |
lock | 总线锁定 |