本文主要是介绍8086汇编语言期末复习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文按本校学习顺序编写,夹带个人记忆私货,不够系统~
第一章 初识汇编语言
1、程序语言分类(机器语言、汇编语言、高级语言)
汇编语言:使用指令助记符,符号地址,标号等符号书写的语言
2、汇编语言意义
与硬件关系密切,硬件类课程和操作系统课程的先行课
有利于理解软件程序的工作原理
执行效率高,占用空间小
3、应用领域
加密解密 逆向分析 病毒分析与防治 网络安全
驱动程序开发
4、实践 Hello World
汇编环境:DosBox masm
.model tiny 1.model存储模式伪指令
.code 2.code段定义伪指令
.startup 3.程序开发伪指令mov dx,offset string; 4.指定字符串偏移mov ah,9 5.准备使用9号功能int 21h 6.调用Dos系统9号功能显示信息功能
.exit 0 7.exit程序结束伪指令
string db 'Hello,World!',0dh,0ah,'$'; 8.定义字符串
end
(1)model:存储模式伪指令
决定一个程序的规模,确定进行程序调用指令转移和数据访问的缺省属性
Tiny Small Compact Medium Large Huge Flat几种常用模式
(2)定义字符串:0dh,0ah
0dh:回车的ASCII,让光标回到行首(想像成机械打字机x坐标置零,y坐标不变)
0ah:换行的ASCII,让光标前进一行(x坐标不变,y坐标+1)
5、课后作业:
改造Hello,World程序实现输出自己的信息
Name:xxxx
Number:xxx
Phone:9389820
Email:xxx@dlu.edu.cn
第二章 计算机中的数据表示
1、二进制的起源与发展
(1)二进制定义 010101001010100
(2)莱布尼茨:提出二进制数的理论与相关运算法则
周文王:易经八卦
冯·诺依曼 电子计算机方案重要设计思想之一:二进制
具有两种稳定状态的元件(晶体管的导通于截止,继电器的接通和断开,电脉冲的高低电平)很容易找到。
2、常用数制及相互转换方法
(1)数制
基数:数制基本特征数,即所用到数字符号的 个 数。eg:2
权:数制中各位1所表示的值 eg:2^i
二进制:基数2 符号0,1
十六进制:基数16 符号0~9+ABCDEF
(2)十进制转换二进制
整数部分 除二取余法
小数部分 乘二取整法
(3)其他数制之间的直接转换法
8进制对应3位2进制 16对应4
3、计算机中的数据表示
!!(1)数
整数:无符号整数 有符号整数
I. 无符号整数的表示:原码
eg:8位无符号数的取值范围:0~255
II. 有符号整数的表示:补码
二进制数最高位定义为符号位 0为正数 1为负数
(带符号位原码直接相加减是错误的,反例:1:0000 0001 -1:1000 0001
1+(-1)=1000 0010=-2显然是错的)
若x>0,补码反码原码一样的
若x<0,补码=反码+1
反码:原码符号位不变,其他取反
n位补码表示的数值:-2^(n-1)~+2^(n-1)-1
补码作用:使符号位能够与有效值一起参加运算,从而简化运算规则
使减法运算转换为加法运算,进一步简化计算机中运算器的线路
几种常见数据类型的取值范围:
char 有符号8位整数 -128~127 unsigned char 无符号8位整数 0~255
short有符号16位整数 -32768~32767 unsigned short 无符号16位整数 0~65535
int有符号32位整数 unsigned int 无符号32位整数
long有符号64位整数 unsigned long无符号64位整数
小数:定点数,浮点数
I.约定所有数值数据的小数点隐含在某一个固定位置上(就规定有几位)
通常采取两种简单约定:将小数点的位置固定在数据的最高位之前(定点小数)或最低之后(定点整数)
缺点:太僵硬 不利于表达特别大or小
II.浮点数
eg:193=0.193*10^3
抽象:N=M*R^C M为尾数,C为阶码(对于二进制数 R=2)
IEEE 754浮点数标准结构:(单精度/双精度)
单精度:32位,1+8阶+23尾 双精度:64位 1+11+52(精度比较高,尾数当然要长些)
阶码部分使用移码表示,尾数部分使用定点小数补码表示
eg:0.15625->(0.00101)2
即1.01*2^-3
阶码3用移码表示:e=127-3=124=7CH=01111100
移码:补码的基础上将符号为取反
尾码01表示为0100000000000000000000000(23位)
所以IEEE754编码为:0 01111100 010000000000000000000000(23位)
(2)字符的二进制表示
英文字符编码:ASCII码
格式:7位二进制代码(比较特殊)
0-9: 30-39(16进制)A-Z 41开始 a-z 61开始
!!最高位通常置为0,有时候用作奇偶校验位
中文字符编码:GB2312
格式:2字节
(3)图像的二进制表示
采样(多少个像素点)&量化处理(颜色)
(4)声音的二进制处理
PCM脉冲编码调制
首先通过麦克风转换成一系列电压变化的信号
随后通过等时距分割,划为离散的信号
(5)视频的二进制表示
最小单位:帧
采样频率、采样深度
!!(6)可执行文件的二进制表示
可执行文件包括:指令和数据
指令:二进制的机器码,指导CPU进行何种指令
数据:二进制表示的数据,字符等,供指令进行存取操作
第三章 CPU架构
0、分析高级语言程序的运行过程 VC disassembly
1、CPU架构的深入解读
(1)中央处理器
包括:多种寄存器、指令执行的运算和控制部件
早期处理器:电路决定算法
后来:允许使用插孔和插线对计算机系统进行改写(受限于插孔数)
后来进化成三线到八线的解码器
计算机设计师发现插孔和内存中各个位之间的关系,发现可以将机器指令的数值表示存储在主存中,当CPU需要执行指令的时候可以从内存中取得指令的数值表示,将该二进制数装入到一个特殊的寄存器中并对指令进行编码。
所以他们给CPU添加了电路控制单元CU,控制单元使用专用寄存器——指令指针寄存器 来保存指令的二进制(操作码)的地址,控制单元从内存中取得指令的操作码,放入指令译码寄存器执行。指令执行完毕后控制单元递增指令指针。
(2)8086功能结构
BIU总线接口单元:读取指令和操作数
EU:指令译码和执行
指令执行的过程:
1、从存储器中每次读取一条指令
2、执行指令
(3)8086寄存器组
执行单元EU中:
8个通用寄存器 16位 AX BX CX DX SI DI BP SP 前四个可以分为高低八位
首先,数据寄存器
AX:累加器,用于算数逻辑运算与外设传输信息
BX:基址寄存器,常用做存放存储器地址
CX:计数器,存放循环和串操作指令中的隐含计数器
DX:数据寄存器,用来存放双字长度的高16位或存放外设端口
然后,变址寄存器(存储器寻址时提供地址)!!注意在串操作指令中的应用
SI:源变址寄存器
DI:目的变址寄存器
另外,指针寄存器
SP:堆栈寄存器,指示栈顶的偏移地址(不能用作其他目的)
BP:基址指针寄存器,表示数据在堆栈段中的基地址
解释:
堆栈:主存中一个特殊的区域,采用先进后出的原则,由CPU自动维持。8086中由堆栈段寄存器SS和堆栈指针寄存器SP共同指示
1个指令指针寄存器
IP:指示代码段中指令的偏移地址
和代码段寄存器CS连用确定吓一跳指令的物理地址
计算机通过CS:IP寄存器来控制指令序列的执行流程
IP是专用寄存器
1个标志寄存器
FLAG反应指令执行结果或控制指令执行的形式
掌握九种标志(重点是前六种)
CF:观察最高位,无符号数运算结果的最高有效位有进位时CY=1 否则NC=0
ZF:观察所有位,全是零时ZR=1(进位溢出不算) ,否则NZ=0
SF:观察最高位,运算结果最高位为1,NG=1,否则PL=0(缺1所以需要plus)
OF:对于有符号数的运算,若算术运算的结果有溢出OV=1,否则NV=0
翻译:因为是有符号数,如果两个正数(首位为0)加在一起产生进位1,那我们会以为它变成负数了,这时候就叫溢出。我们所以为的最高位超出那不叫溢出,用CY表示
PF:最低字节(最低8位)中1的个数为0或偶数PE=1,否则PO=0
⚠️:即使对十六位字操作,PF所反映的也仅仅是最低8位的奇偶性
AF:辅助进位标志 ,运算时低半字节(0-3位)有进位或者借位时,AC=1,否则NA=0
主要是处理器内部用于十进制运算调整指令
DF方向标志:用于串操作指令中控制地址的变化方向
设置UP=0,存储器地址自动增加
设置DN=1,存储器地址自动减少
IF中断允许指令:控制外部可屏蔽中断是否可以被处理器响应,EI=1 DI=0 (不重点)
TF陷阱标志:用于控制处理器进入单步方式,TF=0,正常工作;TF=1,单步执行指令
处理器在每条指令执行结束时便产生一个编号为1的内部中断
4个段寄存器(地址总线多于位数的古早产物,不做要求)
调试debug:
a汇编 u反汇编 d显示数据 e修改数据 r寄存器 rf寄存器 t单步执行 p进程命令(跳过函数)
g断点执行 N文件命名 W写盘操作 Q推出
第四章 8086内存管理
一、8086存储器组织
存储器分类:内存(CPU直接访问,速度快,断电GG)、外存(长期保存大量数据,成本低,容量大)
寄存器是微处理器内部暂存数据的存储单元,存储器是微处理器外部存放程序及数据的空间
程序及数据可以长期存放在外存,在程序需要的时候再进入主存
主存储器通过地址区别进行功能
基础概念:
存储单元:每个存储单元一个编号,称存储器地址
存储内容:每个存储单元存放一个字节的内容eg【0002H】=34H 0002单元内存放有数据34H
数据信息单位:bit二进制位、字节byte 8bit、字Word 16bit、双字DWord 32bit
最低有效位LSB:数据的最低位D0位
最高有效位:数据的最高位,对应字节、字、双字(7、15、31位)
1、存储格式
占据连续的多个存储单元,低字节存入低地址,高字节存入高地址
表示时用低地址表示,例如:
地址对齐:同一存储器地址可以是字节单元地址,字单元地址,双字单元地址等
(选学)8086内存范围:
8086CPU有20条地址线,最大可寻址空间为1MB
8086寄存器最大16位,显然一个寄存器不能确定某一内存单元的20位物理地址
因此8086CPU将1MB空间分割为许多逻辑段:
用一个寄存器表示某段在内存空间内的起始地址(段地址),另一个寄存器表示段内某内存单元相对于起始地址的距离(偏移地址),这样用2个16位寄存器就可以表示20位地址了
限制🚫:每段最大限制为64KB,使得偏移量可以放在一个16位寄存器中,最小的段没有限制
段基址必须定位在地址为16的整数倍上
4个段寄存器:
CS SS DS ES 指明:代码、堆栈、数据、附加段的起始地址
二、8086寻址方式(重点!!!)
指令组成:操作码、操作数
操作码:说明计算机要执行哪一种操作,如传送、运算、移位、跳转等操作
操作数:指令执行的参与者,即各种操作的对象
⚠️每种指令的操作码用唯一一个的助记符表示,对应着机器指令的一个二进制编码
寻址方式:处理器根据指令中的信息来寻找有效地址,从而确定本条指令的数据地址以及下一条指令地址。
指令中的操作数,可以是具体数值,寄存器,存储器地址
指令助记符格式:操作码 操作数1,操作数2;注释
操作数2:src源操作数 表示参与指令操作的一个对象
操作数1:dest目的操作数 存放指令操作的结果
传送指令MOV
MOV dest,src
8086寻址(数据存取)方式
(1)立即数寻址方式:操作数直接存放在机器代码中,紧跟在操作码后;称为imm;通常用来给寄存器赋值
(2)寄存器寻址方式:操作数存放在CPU的内部寄存器reg中
(3)存储器寻址方式:指令中给出操作数的主存地址信息(偏移地址EA),段地址在默认的或用段超越前缀指定的段寄存器中
段超越前缀:
SP比较特殊,有专用用途不能随便用
细分有5种:
1、直接寻址方式:有效地址在指令中直接给出
默认段地址在DS段寄存器,可以使用段超越前缀改变
2、寄存器间接寻址方式 :有效地址存放在基址寄存器BX或者变址寄存器SI、DI中(BP也跑得通)
默认段地址在DS段寄存器,可以使用段超越前缀改变
3、寄存器间相对寻址方式
有效地址是寄存器内容与8位或16位位移量之和,寄存器可以是BX、BP或SI、DI
有效地址=BX/BP/SI/DI+8/16位位移量
4、基址变址寻址方式:有效地址=BX/BP+SI/DI(除了SI,DI其他的寄存器不行,前后调换顺序无所谓)
段地址对应BX基址寄存器默认是DS,对应BP默认是SS
5、相对基址变址寻址指令:BX/BP+SI/DI+8/16位偏移量
c语言中的指针(可在vc中反汇编查看)
第五章 8086指令系统 数据传送指令、算术运算指令&BIOS
第5-8章学习8086汇编相关指令,包括传送指令、加减法指令、逻辑运算与移位指令、控制转移指令、字符串输入输出功能调用指令。用得越多,记得越牢!
一、概述
1、什么是指令系统
该计算机能够执行的全部指令集合
每种计算机都有他支持的指令集合
2、8086指令系统概述
6大组:数据传送类、算术运算类、位操作类、串操作类、控制转移类、处理机控制类
⚠️:指令的功能及名称、指令支持的寻址方式、指令对标志的影响、特殊方面
二、数据传送类
通用数据传送指令:MOV XCHG XLAT
堆栈操作指令:PUSH POP
地址传送指令:LEA
输入输出指令:IN OUT
⚠️:数据传送类指令对标志位没有影响
2.1通用数据传送指令
MOV传送指令:把一个字节或字的操作数从源地址传送至目的地址
寻址方式:
立即数传送 mov al,04h
寄存器传送 mov ax,dx
存储器传送 mov ax,[0222]
段寄存器传送 mov [si],ds mov ax,es mov ds,ax
常见错误:
1、两个操作数类型不一致 mov al,050A
2、两个操作数不能都是存储器(主存之间不能相互传递,需要temp)mov buffer1,buffer2
3、 段寄存器的操作有所限制(段寄存器间不能相互传,需要temp)mov ds,ss
不允许将立即数传送给段寄存器 mov ds,100
不允许直接改变cs值(dosbox能够跑通,但是别这样干) mov cs,100 ; mov cs,[si]
注意:对于存储器单元与立即数同时作为操作数的情况,必须指明:byte ptr指示字节类型,word ptr指示字类型
XCHG交换指令:将两个地方的数据进行互换
寻址方式:reg,reg/mem
寄存器与寄存器之间对换数据 xchg ax,bx
寄存器与存储器之间对换数据 xchg ah,al
常见错误:
1、不能在存储器与存储器之间对换数据 mov [01],[02]
2、长度要一致不能bx和al互换 mov bx,al
3、reg不能是段寄存器
XLAT换码指令:将BX指定的缓冲区中、AL指定的位移处的一个字节数据取出赋给AL
XLAT:al<-ds:[bx+al] 没有显式操作数
执行前:在主存建立一个字节量表格,内含要转换成的目的代码表格首地址存放在BX,AL存放相对表格首地址的位移量。
执行后:将AL寄存器的内容转换为目标代码
mov bx,100
mov al,03
xlat
2.2堆栈操作指令
堆栈是一个后进先出的主存区域,位于堆栈段中,SS寄存器记录其段地址。
堆栈只有一个出口,即当前栈顶。用栈顶指针SP指定。栈顶是地址较小的一端,栈底不变。
PUSH进栈指令:SP-2,然后将一个字操作数存入堆栈顶部(低地址)
寻址方式:
PUSH r16/m16/seg push ax;push[2100h];push cs;
常见错误:
长度不匹配 push ah; push al;
POP出栈指令:将栈顶的一个字传送至指定目的操作数,然后SP+2
寻址方式:
POP r16/m16/seg pop ax;pop[2012h]
⚠️:相当于 r16/m16/seg<-SS:[SP]; SP=SP+2
常见错误:
长度不匹配 pop ah;
堆栈的特点:
操作单位是字,进栈和出栈都是对字量进行
压栈或弹栈都是低地址送低字节,高地址送高字节
可以用存储器寻址方式随机存取堆栈中的数据
堆栈常用来:临时存放数据、传递参数、!!!保存和恢复寄存器
2.3地址传送指令:地址传送指令将存储器单元的逻辑地址送至指定的寄存器
LEA有效地址传送指令(不是获取存储器单元的内容!):将存储器操作数的有效地址传送至指定的16位寄存器中
寻址方式:
LEA r16,mem
eg:mov bx,0400
mov si,3ch
lea bx,[bx+si+0f62h];=139Eh
常见错误:源操作数只能是mem!!!!
特点:获取的是主存单元的有效地址,不是物理地址,也不是该单元的内容;可用来实现计算功能
2.4输入输出指令(暂时不做要求)
三、算术运算指令
算术运算指令实现二进制数目的四则运算。
加法指令:ADD ADC INC
减法指令:SUB SBB DEC NEG CMP
乘法指令:MUL IMUL
除法指令:DIV IDIV
(其中掌握加法与乘法的8个指令)
加法指令ADD
ADD指令将源与目的操作数相加,结果送到目的操作数
ADD指令按照状态标志的定义相应设置
寻址方式:
ADD reg,imm/reg/mem
ADD mem,imm/reg
常见错误:
1、源操作数和目标操作数类型不匹配 eg:add al,2050h
2、目的不能是立即数和CS段寄存器 eg:cs,2050h add 2050,ah
3、两个操作数不能同时为存储器操作数 eg:add btye ptr [200h], byte ptr[100h]
4、对于ADD mem,imm的形式,要指明mem的长度类型 eg: add [200h],05h
对标志位的影响:
1、按照标志的定义相应设置 CF OF SF ZF AF PF
重点:CF、OF
两数相加:
(80+80 10000 0000 OF怎么变?)
ADC 带进位加法指令
ADC将源与目的操作数相加再加上CF标志结果(1)送到目的操作数
ADC与ADD配合,实现多精度加法运算
寻址方式:
ADC reg,imm/reg/mem
ADC mem,imm/reg
常见错误:
1、长度不匹配,mem与mem直接运算
2、adc与add不同可以直接 adc [200],ax
符号位改变:
双字加法:
计算0234 4652h+F0F0 F0F0h
add指令只能对字节和字进行操作,这里需要cf辅助
先对低字进行计算,然后对高字进行计算
mov ax,4652h;ax=4652h
add ax,0f0f0h;ax=3742h CF=1
mov dx,0234h;dx=0234
adc dx,0f0f0h;dx=f325(本来应该是f324的,因为有cf=1),CF重新=0
增量指令INC
INC指令对操作数+1
寻址方式:INC reg/mem eg:inc byte ptr [bx]
对标志位影响:INC指令不影响进位CF标志!!!其他正常
常见错误:对存储器进行修改时不指定ptr
减法指令SUB
SUB将目的操作数减去源操作数,结果送到目的操作数(注意顺序!前者被减)
寻址方式:SUB reg,imm/reg/mem; SUB mem,imm/reg
对标志位影响:正常
常见错误:
1、长度不匹配
2、目标不能是立即数和CS段
3、两操作数不能同时为存储器操作数
4、要指明mem的ptr长度类型
举例:
通过这个例子我们可以知道计算机内对于无符号数和有符号数通过flag位进行区分
此外,CF和OF的确定方法:看所表示的数目是否在表示域内
带位减法指SBB:
SBB将目的操作数减去源操作数,再减去借位CF结果送到目的操作数
SBB指令通常与SUB配合,实现多精度减法运算
寻址方式:SBB reg,imm/reg/mem
SBB mem,imm/reg
常见错误:跟ADC差不多
双字减法:
从低字开始进行处理
eg:0234 4652h-f0f0f0f0h
mov ax,4652h;ax=4652h
sub ax,0f0f0h;ax=5562h,CF=1
mov dx,0234h;dx=0234h
sbb dx,0f0f0h;dx=1143h,CF=1(本来应该是1144h的但因为借位所以不同了)
减量指令DEC
DEC指令对操作数减1
对标识位的影响:DEC不影响进位CF!!其他正常
寻址方式:DEC reg/mem
常见错误:不规定mem的类型
⚠️INC和DEC斗志单操作数指令,主要用于对计数器和地址指针的调整
求补指令NEG
NEG指令对操作数执行求补运算,用0减去操作数然后结果返回操作数
也可以理解为操作数按位取反后加1
对标志位影响:正常,用0减去操作数CF一般为1,除非0000h
寻址方式:NEG reg/mem
比较指令 CMP
CMP将目的操作数减去源操作数,不返回源操作数
执行指令后可以根据标志位的情况判断两者是否相等(ZF=1)大小关系(CF)等
寻址方式:CMP reg,imm/reg/mem
CMP mem,imm/reg
常见错误:就那几个,注意一下mem,imm的情况要指定mem的规格
乘法指令MUL IMUL
MUL无符号字(节)乘法
IMML有符号字(节)乘法
寻址方式:MUL r8/m8(AX<-AL*r8/m8)
MUL r16/m16(DX.AX<-AX*r16/m16)
IMUL类推
对标志的影响:乘法指令影响OF和CF
MUL如果乘积的高一半(AH/DX)为0,CF=OF=0,否则OF=CF=1
IMUL如果乘积的高一半是低一半的符号扩展,OF=CF=0,否则OF=CF=1
!!!乘法指令对于其他标志没有定义(不可预测的),和对标志没有影响不同
符号扩展:用一个操作数的符号位(最高位)形成另一个操作数(全0或者全1)
符号扩展指令(了解)CBW CWD
CBW:将AL的符号扩展到AH
CWD:将AX符号扩展至DX
符号扩展指令常用于获得倍长的数据
除法指令 DIV IDIV
寻址方式:
DIV r8/m8 AL<-AX div r8/m8的商 AH<-AX div r8/m8的余数
DIV r16/m16 AX<-DX.AX div r16/m16的商,DX<-DX.AX div r16/m16的余数
IDIV类似
对其符号位不做要求
ROM-BIOS中断服务
是固化在系统内部的函数集合,通过中断服务和系统控制硬件资源
主板的BIOS负责初始硬件检测和系统引导
举例:VGA BIOS处理所有屏幕处理函数(int 10文字、绘图显示模块)
固定硬盘BIOS管理硬盘驱动器(int13 软盘/硬盘/光驱读写)
PC组织架构:硬件系统、操作系统、应用程序
DOS系统调用:
DOS是位于低级BIOS上的一个软件层,通过DOS系统调用提供进入这些低级BIOS的接口
DOS操作系统为程序员提供的函数库包括信息输入输出和文件操作等功能
比如9号功能显示字符串
Windows API:
Windows操作系统为程序员提供的函数库,包括各种常用操作
常用功能:
BIOS中断:置光标位置 调用号2
参数:BH=页 DH=行 DL=列
BIOS中断:在光标位置显示字符 调用号9
参数:BH=页 AL=字符 BL=属性 CX=字符重复次数
BIOS中断:显示字符串 调用号13H
参数:BP=串地址 CX=串长度 DH,DL=起始地址 BH=页 AL=0 BL=字符属性
字符属性:
字符的颜色,背景颜色,是否闪烁,有无下划线
第七章 位操作类指令
为操作类指令是以二进制位为基本单位进行数据的操作,注意其对标志位的影响
1、逻辑运算指令
AND OR XOR NOT TEST
2、移位指令
逻辑、算数移位指令:SHL SHR SAL SAR
循环、带进位的循环移位指令:ROL ROR RCL RCR(类似推箱子)
逻辑运算指令
1、与AND
只有两位都是1时结果为1,否则为0,结果送到目的操作数
寻址方式:AND reg,imm/reg/mem
AND mem,imm/reg
对标志位的影响:AND指令设置CF=OF=0,根据结果设置SF、ZF和PF状态,对AF未定义
2、或OR
对两个操作数执行或运算,只要有一位是1结果就是1,结果送到目的操作数
寻址方式:OR reg,imm/reg/mem
OR mem,imm/reg
对标志位的影响:OR指令设置CF=OF=0,根据结果设置SF、ZF和PF状态,对AF未定义
3、异或XOR
两位不相同为1,否则为0,结果送到目的操作数
寻址方式:XOR reg,imm/reg/mem
XOR mem,imm/reg
对标志位的影响:XOR指令设置CF=OF=0,根据结果设置SF、ZF和PF状态,对AF未定义
4、非NOT(单操作数指令)
按位取反
寻址方式:NOT reg/mem
对标识位:NOT不影响操作位
逻辑运算综合例题:(注意标志位)
逻辑指令应用: (注意用法)
5、测试指令TEST
对两个操作数执行逻辑与AND计算,结果不送回目的操作数
寻址方式:
TEST reg,imm/reg/mem
TEST mem,imm/reg
对标志位的影响:AND指令设置CF=OF=0,根据结果设置SF、ZF和PF状态,对AF未定义
移位指令
移位指令将操作数移动一位或多位,包括
逻辑移位指令,算术移位指令
循环移位指令,带进位的循环移位指令
首先:逻辑移位SHL SHR
SHL reg/mem,1/CL 逻辑左移,最高位进入CF,最低位补0
SHR reg/mem,1/CL 逻辑右移,最低位进入CF,最高位补0
(推箱子,多推几次就全部变成0了)
然后:算数移位SAL SAR
SAL reg/mem,1/CL 算数左移,和SHL一个东西完全一致
SAR reg/mem,1/CL 算数右移,最低位进入CF,最高位不变
常见错误:SAR ax,9(大于1都要保存在CL中)
移位指令的操作数:
移位指令的第一个 操作数是指定的被移位的操作数,可以是寄存器或存储单元
后一个操作数表示移位位数,该操作数为1,表示移动一位;当移位位数大于1时,用CL寄存器值表示,该操作数表达为CL
移位指令对标志的影响
1、按照移入的位设置进位标志CF
2、根据移位后的结果影响SF、ZF、PF
3、对AF没有定义
4、如果进行1位移动,按照操作数的最高符号位是否发生改变,相应设置OF(有变化OV=1,无变化OF=0)
移位指令的意义
逻辑移位:无符号数处理
SHL:无符号数*2,CF反应进位
SHR:无符号数div 2,商在目的操作数中,余数由CF标志反映
算数移位:有符号数处理
SAL:若符号位不变,相当于有符号数*2,否则运算不正确
SAR:相当于有符号数 div2,商在目的操作数中,余数由CF反应
使用移位指令将一个数扩大或缩小2^n倍,比使用乘法或者除法指令快
移位乘法:
循环移位指令ROL、ROR、RCL、RCR
将操作数从一端移出的位返回到另一端形成循环,分为不带进位和带进位,分别具有左移或右移操作
不带进位:CF由最低位/最高位决定
ROL reg/mem,1/CL;不戴进位循环左移
ROR reg/mem,1/CL;不戴进位循环 右移
带进位:CF参与循环之中
RCL reg/mem,1/CL;带进位循环左移
RCR reg/mem,1/CL;带进位循环右移
循环移位指令对标志的影响
1、按照指令功能设置CF
2、不影响SF、ZF、PF、AF
3、若进行一位移动,则按照操作数的最高符号位是否改变设置OF,有变化设置1无变化设置0
例题:
第八章 控制转移类指令
控制转移类指令用于实现分支、循环、过程等程序结构,是仅次于传送指令的最常用命令
重点:JMP/JCC/LOOP CALL/RET INT n常用的系统功能调用
了解 LOOPZ/LOOPNZ
一、无条件转移指令:
JMP label;程序转向label标号指定的地址
只要执行无条件转移指令,就使程序转到指定的目标地址处,从目标地址处开始执行那里的指令
操作数label就是要转移到的目的地址
JMP指令分成4种类型
段内(段间)转移,直接(间接)寻址
解读:目标地址的寻址方式
直接寻址方式:用标号表达
转移地址像立即数一样,直接在指令的机器代码中,就是直接寻址方式
间接寻址方式:用寄存器或存储器操作数表达
转移地址在寄存器或主存单元中,就是通过寄存器或存储器的间接寻址方式
(1)段内转移、直接寻址
JMP label;ip=ip+位移量
位移量是紧接着JMP指令后的那条指令的偏移地址到目标指令的偏移地址的地址位移
当向地址增大方向转移时,位移量为正;减小为负
(2)段内转移,间接寻址
JMP r16/m16 ;ip=r16/m16
将一个16位寄存器或主存字单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容
二、条件转移指令
JCC label;指定的条件CC如果成立,程序转移到由标号label指定的目标地址去执行指令; ip=ip+8位偏移量(!!注意不是16位)
条件不满足,顺序执行
操作数label采用短转移,称为相对寻址方式
JCC指令分类:不影响标志,但要利用标志
分为3种情况:
1、判断单个标志位状态 5个标志位
(1)JZ/JE和JNZ/JNE
利用零标志ZF判断结果是否为零(或相等)
(2)JS和JNS
利用符号标志SF,判断结果是正或负(有符号数)
(3)JO和JNO
利用溢出标志OF,判断结果是否产生溢出
(4)JP/JPE和JNP/JPO
利用奇偶标志PF,判断结果中“1“的个数是奇还是偶
(5)JC和JNC
利用进位标志CF,判断结果是否进位或借位
另解:
2、比较无符号数高低
无符号数的大小用高Above和低Below表示!!!(方便记忆)
利用CF确定高低、利用ZF标志确定相等
两数的高低分成4种关系
(1)低于(不高于等于)JB(JNAE)(CF=1)
(2)不低于(高于等于)JNB(JAE)(CF=0)
(3)高于(不低于等于)JA(JNBE)(CF=0 and ZF=0)
(4)不高于(低于等于)JNA(JBE)(CF=1 or ZF=1)
结果:ax保存较大的无符号数
3、比较有符号数大小
有符号数的大小用Greater和Less还需要组合OF、SF标志并利用ZF标志确定相等
两数的大小分成4种情况
(1)小于(不大于等于)JL(JNGE)(SF!=OF)
(2)不小于(大于等于)JNL(JGE)(SF=OF)
(3)小于等于(不大于)JLE(JNG)(SF!=OForZF=1)
(4)不小于等于(大于)JNLE(JG)(SF=OForZF=0)
符号位变化推导:
例题:
三、循环指令 LOOP
LOOP label;CX!=0 cx=cx-1(记数用)
LOOPZ label ;CX!=0且ZF=1
LOOPNZ label;CX!=0且ZF=0
循环指令默认使用cx计数器,方便实现计数循环
寻址方式:相对寻址!
四、子程序指令CALL、RET
子程序是完成特定功能的一段程序
当主程序需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行
当运行完子程序功能后,采用RET返回指令回到主程序继续执行
执行过程如下:
调用指令CALL
CALL指令分成4种类型(类似JMP)我们只需要掌握段内调用的方式
CALL label;段内调用、直接寻址
CALL r16/m16;段间调用,间接寻址
CALL指令需要保存返回地址:
段内调用——入栈偏移地址IP SP=SP-2,SS:[SP]=IP
返回指令RET
需要弹出CALL指令压入堆栈的返回地址
段内返回——出栈偏移地址IP IP取出来=SS:[SP] 然后SP=SP+2
五、中断指令 INT
中断请求可以来自处理器外部的中断源,也可以由处理器执行指令引起
中断指令的过程:
六、系统功能调用
21H号中断是DOS提供给用户的用于调用系统功能的中断,它有近百个功能用用户选择使用
主要:设备管理,目录管理,文件管理三个方面
ROM-BIOS也是以中断服务程序的形式,向程序员提供系统的基本输入输出程序
汇编语言程序设计需要采用系统的各种功能程序
*充分利用操作系统提供的资源是程序设计的一个重要方面
功能调用的步骤:4步
1、在AH寄存器中设置系统功能调用号
2、在指定寄存器中设置入口参数
3、执行指令INT21H(或ROM—BIOS的中断向量号)实现中断服务程序的功能调用
4、根据出口参数分析功能调用执行
重点!!!输入输出类功能调用
向显示器输出字符
1、字符的输出
功能号:AH=2 入口参数:DL=字符的ASCII码
功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。
2、字符串的输出
功能号:AH=09h 入口参数:DX=想要显示的字符串在主存中的首地址
功能:可以输出回车,换行字符
从键盘输入数据
3、字符的输入
功能号:AH=01h 出口参数:AL=字符的ASCII码
功能:获得按键的ASCII码值
⚠️:调用此功能若没有按键按下,则一直等待,直到按键后才读取该值
4、字符串的输入
功能号:AH=0Ah 入口参数:DS:DX=缓冲区首地址
⚠️:要提前定义好缓冲区
功能:用户按键最后用回车确认
缓冲区定义:
第一个字节:事先填入最多想要接受的字符个数(包括回车字符,可以是1~255)
第二个字节:实际输入的字符个数(不包括回车)
第三子节:存放输入的字符串
(1)实际输入的字符多于定义数时,多出的字符丢弃并响铃提示
(2)扩展ASCII码(功能键等) 占用2个字节,第一个为0
第九章 串操作指令
定义:串操作指令采取比较特殊的数据串寻址方式,操作主存连续区域的数据
重点掌握:MOVS STOS LODS CMPS SCAS REP
REPZ/REPE REPNZ/REPNE
1、串操作对象:
串操作指令的操作数是主存中连续存放的数据串
该数据串是以字W为单位的字串,或是以字节B为单位的字节串
2、串寻址方式:
源操作数用寄存器SI寻址,默认在数据段DS中,但允许段超越
目的操作数用DI寻址,默认在附加段ES中,不允许段超越!!!
每执行一次串操作指令,SI和DI将自动修改
对于字节串+-1,对于字串+-2
执行指令CLD指令后,DF=0,地址指针增1或2
执行指令STD后,DF=1,地址指针减1或2
串传送MOVS
将字节或字操作数从主存的源地址传送至目的地址
MOVSB 字节串传送 ES:[DI]<-DS:[SI]
MOVSW 字串传送 ES:[DI]<-DS:[SI]
串存储STOS
将AL或AX数据传送至目的地址
STOSB 字节串存储:ES[DI]<-AL. DI=DI+-1
STOSW字串存储:ES[DI]<-AX DI=DI+-2
串读取LODS
将指定主存单元的数据传送给AL或者AX
LODSB 字节串读取 AL<-DS:[SI] SI=SI+-1
LODSW 字串读取 AX<-DS:[SI] SI=SI+-2
串比较CMPS
将主存中的源操作数减去目的操作数以便设置标志,进而比较两操作数之间的关系
CMPSB 字节串比较,DS:[SI]<-ES:[DI] SI=SI+-1 DI=DI=-1
CMPSW 字串比较, DS:[SI]<-ES:[DI] SI=SI+-2 DI=DI=-2
串扫描SCAS
将AL/AX减去目的操作数以便设置标志,进而比较AL/AX与操作数之间的关系
SCASB 字节串扫描 AL<-ES:[DI] DI=DI=-1
SCASW 字串扫描 AL<-ES:[DI] DI=DI=-2
重复前缀指令
串操作指令执行一次,仅对数据串中的一个字节或字量进行操作,但是串操作指令前,都可以加一个重复前缀,实现串操作的重复执行。重复次数隐含在CX寄存器中
重复前缀分两类三条指令
配合不影响标志的MOVS、STOS(和LODS)指令的REP前缀
配合影响标志的CMPS和SCAS指令的REPZ和REPNZ前缀
REP重复前缀指令
定义:每执行一次串指令CX减1 直到CX=0,重复执行结束
REP前缀可以理解为:当数据串没有结束(CX!=0),则继续传送
程序段的最后3条指令,可以分别替换为
REP MOVSB和REP STOSW
例如:重复段传送:
重复串存储:
REPZ重复前缀指令
定义:每执行一次串指令CX-1,并判断ZF是否为0,只要CX=0或者ZF=0,重复执行结束
REPZ/REPE前缀可理解为:当数据串没有结束(CX!=0)并且串相等(ZF=1)则继续比较
REPNZ重复前缀指令
定义:每执行一次串指令CX-1,并判断ZF是否为1,只要CX=0或者ZF=1,重复执行结束
REPNZ/REPNE前缀可理解为:当数据串没有结束CX!=0并且串不相等ZF=0,则继续比较
重复比较的解释:
指令repz,cmpsb重复执行的情况
ZF=0即出现不相等的字符
CX=0即比较完所有字符
这种情况下,如果ZF=0,说明最后一个字符不等,而ZF=1表示所有字符比较后都相等
所以重复比较结束后jnz unmat指令的条件成立ZF=0,字符串不相等
处理机控制类指令(不做要求)
对CPU状态进行控制的指令
NOP CS:SS:DS:ES:
LOCK HLT ESC WAIT
汇编语句格式
硬指令:使好CPU产生动作,并在程序执行时才处理的语句
伪指令:不产生CPU动作,再程序执行前由汇编程序处理的说明性语句,例如:数据说明变量定义
(string db'HELLO,world!')
伪指令与具体的处理器类型无关,与汇编程序版本有关
两种语句类型
(1)执行型语句——由硬指令构成的语句,它通常对应一条机器指令,出现在程序的代码段中
(2)说明性语句——由伪指令构成的语句,它通常指示汇编程序如何汇编源程序
(buffer db 1,2,3,4xxxx;数据定义)
两种标识符
保留字
操作数与参数
重点:
变量定义伪指令助记符
变量定义伪指令根据申请的主存空间单位分类
DB——定义字节伪指令
用于分配一个或者多个字节单元,并可以将他们初始化为指定值
初值表中每个数据一定是字节量,存放一个8位数据
(可以是无符号、有符号、字符串常数)
DW——定义字伪指令
类似DB,可用于存放16位数据
(段地址、偏移地址、两个字符、0~65535间无符号、有符号数)
DD——定义双字伪指令
类似,(可以是无符号有符号、16位段地址(高地址)和16位偏移地址(低地址)的远指针)
PTR 使名字或标号具有指定的类型
当前偏移:$
1.$在汇编中有两种意思,在伪指令中指当前指令寄存器的值,在指令中表示当前指令的偏移地址,其实两者都是指令寄存器的值,但是对于指令它也是指令在代码段的偏移地址,于是死循环就可以写为jmp $。
取偏移地址:OFFSET
OFFSET 运算符返回数据标号的偏移量。这个偏移量按字节计算,表示的是该数据标号距离数据段起始地址的距离。
(持续更新中)
这篇关于8086汇编语言期末复习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!