注:参考书是王爽老师的《汇编语言第3版)
1.CPU的组成
运算器用于信息处理;寄存器用于信息存储;内部总线实现cpu内部的各种联系;控制器协调各种器件
8086有14个寄存器
通用寄存器:AX BX CX DX
变址寄存器:SI DI
指针寄存器:SP BP
指针指令寄存器:IP
段寄存器:CS SS DS ES
标志向寄存器:PSW
它们之间的共性在于 寄存器都是16(0-15)位的,可以存放两个字节
思考:如何保证不同代寄存器的兼容性呢?通用寄存器均可以分为两个独立的8位寄存器使用
? ? ? ? ????????因此可以细化,例如 AX分为AH? AL
8086是16位CPU,因此称其字长为16BIT
一个字可以存在一个16位寄存器中,这个字的高位字节存在这个寄存器的高8位寄存器中,这个字的低位字节存在这个寄存器的低8位寄存器
2.mov 和 add 指令
mov:
? ? ? ? mov ax 20;将20送入ax,数字后面不写H默认为10进制
????????mov ax bx;将bx中的送入ax
add:
? ? ? ? add ax 9;将寄存器AX中的数值加上9
???????? add ax bx;ax=bx+ax(需要注意溢出问题)
3.物理地址
cpu访问内存单元是要给出内存单元的地址
所有的内存单元的存储空间是一个以为的线性空间
每一个内存单元在这个空间中都有唯一的地址,这个唯一的地址称作物理地址
事实上,8086有20位地址总线,可以传送20位地址,寻址能力为1M
8086是16位结构的CPU
运算器一次最多可以处理16位数据,寄存器最大宽度也为16位,在8086内部处理与传输、暂存的也是16位,寻址能力也只有64k
解决方案:用两个16位地址合成一个20位的物理地址(段地址,偏移地址)
? ? ? ? 物理地址:段地址*16+偏移地址
4.用分段方式管理内存
需要注意的是,内存并没有分段,段的划分来自于cpu
同一段内存,多种分段方案:
? ? ? ? 段地址*16必然是16的倍数,所以一个段的起始地址也一定是16的倍数,一个段的长度最多为64k
5.CS IP
CS:代码段寄存器
IP:指令指针寄存器
执行何处的指令,取决于cs:ip
6.jmp指令
修改cs:ip的指令
????????debug的R命令可以直接改变寄存器的值
? ? ? ? 不能对cs/ip 使用mov
? ? ? ? 因此使用转移指令jmp :jmp 段地址:偏移地址(如若想要仅仅修改ip的内容, jmp 某一合法寄存器 jmp ax (类似于 mov IP,ax))
7.内存中的字的存储
对于8086cpu,16位作为一个字
高八位放高字节,第八位放低字节
16位的字在内存中需要两个连续字节存储,怎么存放?
? ? ? ? 低位字节在低地址单元,高位字节存在高地址单元
字单元:由连续的两个内存单元组成,存放一个字型数据(16位)
8.DS和【address】
cpu要读取一个内存单元的时候,必须先给出内存单元的地址
DS寄存器存放要访问数据的段地址,偏移地址用[......]给出
同时 ds不支持数据直接送入段寄存器 需要 mov ds bs
9.对内存单元数据的访问
可以根据需要将一组内存单元定义为一个段
物理地址=段地址*16+偏移地址
处理方法:(DS):(【address】)
10.mov指令操作数据
也可以使用 mov 段寄存器,寄存器
? ? ? ? ? ? ? ? mov 内存单元,段寄存器
? ? ? ? ? ? ? ? mov 段寄存器,内存单元
但不可以使用? mov 段寄存器,数据
11.栈操作的实现
push (入栈)
pop? ? ?(出栈)? ?;把栈顶元素赋给到对应寄存器
两者都对字为单位进行操作
栈段寄存器ss:存放栈顶的段地址
栈顶指针寄存器sp:存放栈顶的偏移地址
????????任何时刻,SS:SP指向栈顶元素
12.用汇编语言编写源程序
;伪指令
assume cs:coding;假设假设某一段寄存器与段相关联
codesg segment;段定义,存放代码,数据和栈空间,此处为段的开始
codesg ends;此处为段的结束
end;汇编程序的结束标志,每个汇编程序结束都要加
;程序返回
mov ax,4cooh
int 21h
源程序.acs经过编译连接后变为.exe
13.[...]和(...)
[...]表示一个内存单元,汇编语法规定
(...)表示一个内存单元或者寄存器里面的内容,为方便学习做出的约定,例如(ax)=0010H;只能用寄存器以及物理地址
再约定:idata表示常量,例如move ds,idata
14.inc指令
操作内容+1
15.Loop指令
loop 标号
? ? ? ? 功能:实现循环
(需要注意的是,汇编程序中,数据不能以字母开头,因此形如ffff前面需要加0)
16.引入段前缀
mov?al,[0];将DS:0储存单元的值传给AL,然而经过汇编后,含义变了
;对策是在【IDATA】前显示地写上了段寄存器
;mov al,ds[bx]
;mov al,ds:[bx]
访问连续的内存单元:使用loop和[bx]
注意:在汇编中直接写入地址是很危险的
dw;define word 定义字型数据,定义一个字,如0123H
db;定义一个字节
dd;定义一个双字
;以上定义不属于真正的代码
;可以通过定义一个标号,知识代码开始的位置,程序加载后,CS:IP指向要执行的第一条指令在start处
例如? ?start:
? ? ? ? ? ?end start
17.将数据、代码、栈放入到不同段之中
? ? ? ? data segment
? ? ? ? data ends
? ? ? ? stack segment
? ? ? ? stack ends
? ? ? ? code segment
????????;初始化各段寄存器
? ? ? ? ;入栈
? ? ? ? ;出栈
? ? ? ? code ends
18.处理字符问题
汇编程序中,用‘......’表示数据是以字符形式给出的,编译器将把他们转化为相对应的ASCII码
小写字母的ASCII码值比大写字母的码值大20H(32)
逻辑与指令:
and? des,src;与运算
or??dest,src;或运算
19.【bx+idata】寻址方式
[bx+idata]表示一个内存单元,他的偏移地址为(bx)+idata
20.SI和DI寄存器
变址寄存器:执行和地址有关的操作
功能类似于BX,不同在于SI和DI不能分成两个八位寄存器来使用
21.【bx+si】和【bx+di】方式指定地址
【BX+SI】表示一个内存单元,即BX中的数值加上SI中的数值
适用于一维数组的寻址
mov ax,[bx+si]
将一个内存单元的内容送入AX
这个内存单元的长度为2字节(字单元),存放一个字
偏移地址为BX中的数值加上SI中的数值
段地址在DS中
22.【bx+si+idata】和【bx+di+idata】方式指定地址
【bx+si+idata】表示一个内存单元
mov ax,[bx+si+idata]
将一个内存单元内容送入ax
这个内存单元为两字节,是字单元,存放一个字
偏移地址为bx中的数值加上si中的数值再加上idata,段地址在ds中
23.内存的寻址方式
24.用于寻址的寄存器
BX,SI,DI,BP可以用在【...】对内存进行单元寻址,bx以外的通用寄存器,段寄存器军不可以
此外【bx+bp】和【si+di】是错误的
BX和BP的区别在于:BX默认指的是DS段,而BP默认指的是SS段
25.数据在哪里?有多长?
汇编语言中数据位置的表达
????????1.立即数 idata? 2.寄存器? ?3.内存:段地址和偏移地址
处理的数据有多长?
? ? ? ? 字操作 /字节操作 /word ptr 或者byte ptr指明长度
? ? ? ? ;把 字1 赋值给 ds段的 第0内存
26.div指令
div是除法指令,被除数默认放债AX或DX和AX中,除数8位或16位,在寄存器或者内存单元中
被除数 AX? DX和AX
除数? ?8位寄存器? ?16位内存或寄存器
商? ? ? ?AL? ? ? ?AX
余数? ? AH? ? ? DX
切记提前在默认的寄存器中设置好被除数,且默认寄存器不作别的用处
27.dup功能与用法
dup和dp/dw/dd等数据定义伪指令配合使用,用来进行数据的重复
? ?
? ??
28.offset
格式:offset标号
用于取得标号的偏移地址
29.jmp指令
无条件转移
可以仅仅修改IP,也可以同时需改cs和ip
jmp指令要给出两种信息:转移的目的地和转移的距离
根据转移距离的不同:
jmp:根据位移进行转移????????
? ? ? ? JMP short 的机器指令中,包含的是跳转到指令的相对位置,而不是转移的目标位置
????????
30.jcxz指令
指令格式:jcxz标号
功能:如果(CX)=0,则转移到标号处执行,当不等于0时,什么也不做(程序向下继续执行)
其中所有的条件转移指令都是段转移
ip修改范围位-128-127,在对应的机器码中包含转移的唯一,而不是目的地址
31.call和ret指令
call指令:调用子程序,实质上时流程转移,实现方法和jmp指令的原理类似
将当前的ip或ip和CS压入栈中,转移道标号中执行指令
相当于:
push ip
jmo near ptr 标号
? ? ? ? 注意:call far ptr ;实现段间转移
? ? ? ? ? ? ?
32.ret和retf
? ? ? ? ? ? ? ? ? ? ? ? ? ?
??????
33.mul指令(乘法指令)
? 格式:
mul? 寄存器
mul? 内存单元
????????
34.标志寄存器
flag
16位寄存器,按照位起作用,每一位都有专门的含义,记录特定的信息
用来存储相关指令的执行结果
可以位cpu执行相关指令提供行为一句
用来控制cpu的相关工作方式
ZF-零标志
PF-奇数偶数标志
PF记录执行指令后,结果所有二进制位中1的个数
1的个数为偶数PF=1,为奇数PF=0
SF-符号标志
SF执行指令后,将结果计数视为有符号数
结果为-那么,SF=1,反之结果为+,SF=0
CF-进位标志
在进行无符号运算时,CF记录了运算结果最高有效位向更高位的进位值,或从更高维的错位值
CF记录指令执行后,有进位或者借位,CF=1,反之CF=0
OF-溢出标志
在进行有符号数进行运算时,如果结果超过了机器所能表示的范围,那么则称为一处
OF记录有符号数操作指令执行后,有一处,OF=1,反之OF=0
35.adc-带进位的加法指令