July 14, 2020 6:46 PM
参考 看雪-汇编快速入门
1.参考资料
《汇编语言(第3版)》王爽著 等
2.课程资源
看雪论坛:http://bbs.pediy.com/
链接: https://pan.baidu.com/s/17Yuz0YgpHJd6k1YEuwavBg 提取码: xkt7
机器指令能被计算机直接识别。
汇编指令需要通过编译器转为机器指令。
汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。
在不同的设备中,不同的机器语言指令集。
进制:一种逢N进一的运算,最小值0,最大值N
转换方法:
十进制转二进制:除2取余
二进制转十进制:加权
二进制转十六进制:4位一组
计算机:
输入设备 输出设备 存储器 运算器 控制器
存储单位
计算机中最小的信息单位bit(比特),二进制单位
计算机中存储数据的最小单位是Byte(B字节)
1TB=1024GB=10242014MB=102410241024KB=1024102410241024B
存储单元
存储器被划分成了若干个存储单元,一个存储单元可以存储一个字节(8个二进制位),每个存储单元从0开始顺序编号。
对于一个有128个存储单元的存储器:容量位128字节,编号0-127.
每个单元有两部分构成:一般用十六进制表示。
存储单元的地址
存储单元的内容
CPU对存储器的读写通过三种总线控制:地址总线、数据中心、控制总线
地址总线:
N跟地址线,宽度位N,即2的N次方个内存单元
数据总线:
一根数据总线可以传输一个0或1,即1bit。
|类别 | 8080 | 8088 | 8086 | 80286 | 80386 |
|地址总线根数|16 |20 |20 |24 |32 |
|地址总线宽度|64KB |1MB |1MB |16MB |4GB |
|数据总线宽度|8 |8 |16 |16 |32 |
|一次传送数据|1B |1B |2B |2B |4B |
CPU如何找到程序即将执行指令位置
-使用寄存器(CS:IP)寻址来确定即将执行指令位置
寄存器是CPU内的组成部分。有限存储容量的告诉存储部件,可以用来暂存指令、数据和地址。
-存在于CPU中 用于存储数据 速度快 数量有限
8086CPU:14个寄存器,所有的寄存器都是16位,可以存放两个字节,即一个字
80386CPU:16个寄存器,所有的寄存器都是32位,可以存放四个字节,即两个字
16位CPU所还有的寄存器有(共14个)
4个数据寄存器(AX、BX、CX、DX)
2个变址寄存器(SI和DI)
2个指针寄存器(SP和BP)
4个段寄存器(ES、CS、SS、DS)
1个指令指针寄存器(IP)
1个标致寄存器(Flags)
32位CPU所含有的寄存器有(共16个)
4个数据寄存器(EAX、EBX、ECX、EDX)
2个变址寄存器(ESI和EDI)
2个指针寄存器(ESP和EBP)
6个段寄存器(ES、CS、SS、DS、FS和GS)
1个指令致志寄存器(EIP)
1个标志寄存器(EFlags)
64位CPU 使用RAX
通用寄存器共8个:数据寄存器、变址寄存器、指针寄存器
--用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果,此外各自具有一些特殊功能。
数据寄存器(8086--16位)
主要用来保存操作数和运算结果等信息.
由AX、BX、CX、DX四个组成
由于8086之前的CPU位8位CPU,为了兼容以前的8位程序,在8086CPU中,每一个数据寄存器都可以当作两个单独的寄存器来使用,由此,每一个16位寄存器可以当作2个独立的8位寄存器来使用。
只有数据寄存器可以拆分为独立8位寄存器
注意:
在16位CPU中,AX、BX、CX、DX不能存放存储单元的地址
在32位CPU中,其32位寄存器EAX、EBX、ECX、EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以这些32位寄存器更具有通用性。
通常文件中至少有两个段
物理地址 = 基础地址 + 偏移地址
基础地址 = 段地址 * 0x10H
物理地址 = 段地址*0x10H + 偏移地址
注意:CPU可以用不同的段地址和偏移地址形成同一个物理地址
段寄存器
8086CPU有4个段寄存器
修改CS:IP
1.同时修改CS:IP的内容:jmp 段地址:偏移地址
2.修改IP的内容:jmp 某一合法寄存器, 好似:mov IP 莫伊合法寄存器
DOSBox DownLoad
1.安装DOSBox环境和Debug.exe
2.配置DOSBox操作目录
安装目录下 DOSBox 0.74-3 Options.bat 鼠标双击,不可以直接编辑
[autoexec]
MOUNT C E:\masmpro
set PATH=$PATH$;E:\masmpro
此外可以动后手动mount。
具体操作见安装目录用户文档,或intro mount
配置后,提示挂载成功。
切换到C: 目录下,dir指令可查看masmpro内文件
3.Debug.exe
MS-DOS Command - DEBUG.EXE
debug是DOS、Windows提供的实模式(8086方式)程序的调试工具。
debug功能
可以查看CPU各种寄存器的内容
可以查看内存的情况
可以在机器码级别跟踪程序的运行
常用操作:
参考 王爽 《汇编语言 第3版》35页
DOSBox下调试(masm、link、debug)简单的汇编语言程序
一个存储单元 有一个物理地址,多个逻辑地址
物理地址:
一个存储单元的编号
每个物理存储单元都有一个20位编号
8086CPU物理地址范围:00000H~FFFFFH
逻辑地址
用户编程时,采用逻辑地址,形式为: 段基地址:段内偏移地址
将逻辑地址左移4位,加上偏移地址就得到20位物理地址
段寄存器与逻辑段
8086CPU有4个段寄存器,每个段寄存器用来确定一个逻辑段的起始位置,每种逻辑段均有各自的用途:
CS(代码段):指明代码的起始地址
利用CS:IP取得下一条要执行的指令
SS(堆栈段):指明堆栈段的起始地址
利用SS:SP操作堆栈顶的数据
DS(数据段):指明数据的起始地址
利用DS:EA存取数据段中的数据
ES(附加段):指明附加段的起始地址
利用ES:EA存取附加段中的数据
EA是偏移地址,称之为有效地址EA
若操作数在主存中,存取的方法有:
没有指明段前缀时,一般的数据访问在DS(数据段)
MOV AX,1000H = MOV AX,DS:[1000H]
标志寄存器
|标志位| 标志位名称及外语全称 | =1 | =0 |
|CF | 进位标志/Carry Flag| 进位 | 无进位 |
|PF | 奇偶标志/Parity Flag| 偶 | 奇 |
|AF |辅助进位标志/Auxiliary Carry Flag | 进位| 无进位|
|ZF | 零标志/Zero Flag | 等于零| 不等于零|
|SF | 符号标志/Sign Flag | 负 | 非负 |
|TF | 跟踪标志/Trace |||
|IF | 中断标志/Interrupt Flag| 允许| 禁止 |
|DF | 方向标志/Direction Flag| 减少| 增加 |
|OF | 溢出标志/Overflow Flag | 溢出| 未溢出 |
状态标志
用于记录程序运行结果的状态信息
CF ZF SF PF OF AF
控制标志
用于控制处理器执行指令
DF IF TF
运算结果标志位:
CF标志(Carry进位,Flag标志):
进位标志位,一般情况,进行无符号运算时,它记录运算结果的最高位向更高位的进位值,或从更高位的借位值,如果运算结果的最高位产生了一个进位或借位,那么其值为1,否则其值为0。
ZF标志(ZeroFlag):
零位标志位,它记录相关指令执行后的结果是否为0,如果是0,那么ZF=1,如果结果不为0,那么ZF=0。
PF标志(ParityFlag):
奇偶标志位,它记录相关指令执行后,其结果的目的操作数最低有效位二进制位中1个个数是否为偶数,如果是偶数,PF=1,反之为0。
SF标志(SignFlag):
符号标志位,它记录相关指令执行后,其结果是否为负,如果结果为负,SF=1,如果非负,SF=0。
OF标志(Overflow溢出,Flag标志):
溢出标志位,在进行有符号数运算的时候,如果结果超出了机器所能表示的范围称为溢出,OF的值被置为1,否则OF的值为0。
注意:这里所说的溢出,只是对有符号运算而言。
有符号时,运算结果值不正确。
AF标志(Auxiliary Carry Flag)
若运算时D3(低半字节)有进位或借位时,AF=1,否则AF=0;
状态控制标志位:
TF标志(TrapFlag):
追踪标志位,当追踪标志被置为1时,CPU进入单步执行方式,即每执行一条指令产生一个单步中断请求,这中方式主要用于程序的调试。
IF标志(Interrupt-enable Flag):
中断允许标志位,用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求,但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。
当IF=1时,CPU可以相应CPU外部的可屏蔽中断发出的中断请求。
当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。
CPU的指令系统中也有专门的指令来改变标志位IF的值。
DF标志(Direction Flag)
用于串操作指令中,控制地址的变化方向:
设置DF为0,存储器地址自动增加
设置DF为1,存储器地址自动减少
CLD指令用于复位
STD指令用于置位
溢出与进位
有符号、无符号指的是最高位是否是符号位,即是以补码的形式看待还是以源码的形式看待。
溢出标志(OF):表示有符号数运算结果是否超出范围,运算结果已经不正确;
范围:0~255 0~65535
进位标志(CF):表示有符号数运算结果是否超出范围,运算结果仍然正确
范围:-128~127 -32768~32767
一般来说指令是由两部分组成,即操作码和操作数。
操作码: 给出该指令应完成何种操作
操作数: 用来描述该指令的操作对象
在指令中操作码是不可缺少的,但操作数可以没有,也可以有一个操作数或两个操作数
根据操作数的个数,指令格式可以分为以下几种:
1.零操作数指令
指令格式中没有操作数或操作数是隐含约定的
2.一操作数指令
指令格式中有一个操作数,或还有一个隐含的操作数(实际上是双操作数)
3.二操作数指令
指令中有两个操作数,其中一个为 目的操作数,另一个为源操作数
源操作数:只能读取的操作数
目的操作数:即可读取也可写入(存放操作结果)的操作数
指令中指明操作数存放位置的表达方式
寻址方式可以分为:
指令中数据存放的位置,三种:
1.存放指令中(立即数)
操作数包含在指令中,即被曹祖数据直接表示在指令的操作数字段中,紧跟在操作码之后。
2.存放于寄存器中(寄存器操作数)
数据存放在CPU的一个寄存器中
3.存放于存储器中(存储器操作数)
数据在内存中或在I/O端口中,存放数据的偏移地址以某种方式表示在指令中。
例如 MOV AX,[2500H] 其中[2500H]为存储器操作数
存储器操作数中操作数字段至少此操作数的偏移地址,而段地址有某个段寄存器来提供。此例中默认为数据段DS
立即数寻址
操作数为立即数,直接存放在指令的操作数字段中。
立即数寻址时,只允许源操作数为立即数,目标操作数必须是寄存器或存储器,其作用时给寄存器或存储单元赋值。
在汇编中,立即数不能作为指令中的第一操作数。
寄存器寻址
操作数在指令所指示的寄存器中
表示格式:直接在指令中写出寄存器名称
存储器寻址
直接寻址
操作数存在内存中,操作数的偏移地址直接表示在指令中
表示格式:[偏移地址]
默认操作数存放在内存的数据段中
MOV AL,[1964H]
段超越
操作数也允许存放在其他段中(ES,SS),此时应该在指令中指明段超越
:若操作数不在指令默认的段中,而在其它莫格段中,则需要在指令中加以表示,这种情况称为段超越。
MOV AL,ES:[1064H]
间接寻址方式
操作数存在存储器中国,操作数的偏移地址在BX、SI、DI和BP的某个寄存器中。
若以BX、SI、DI作为间接寻址寄存器,则默认操作数存放在数据段中,用DS寄存器中的内容作为地址
若以BP作为间接寻址寄存器,则默认操作数存放在堆栈段中,用SS寄存器中的内容作为地址。
相对寻址方式
操作数在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或变址寄存器(SI、DI)的内容加上指令中给定的8位或16位位移量之和。
基址加变址寻址方式
在基址加变址寻址方式中,通常把BX和BP看作是基址寄存器,把SI和DI看作是变址寄存器。把两种方式组合起来形成一种新的寻址方式。
基址加变址的寻址方式是把一个基址寄存器BX或BP的内容,加上变址寄存器SI或DI的内容,并以一个段寄存器作为地址基准,作为操作数的地址。
相对基址加变址寻址方式
在相对基址变址寻址方式中,通常把BX和BP看作是基址寄存器,把SI和DI看作是变址寄存器。它是把一个机制寄存器BX或BP的内容,加上变址寄存器SI或DI的内容,再加上指令中给定的8位或16位位移量,并以一个段寄存器作为地址基准,作为操作数的地址。
包括:
通用传送指令;所有通用传送指令都不影响标志位
1)基本传送指令(MOV)
指令格式 MOV DST,SRC
源操作数和目的操作数可用6中寻址方式的任何一种
操作:将SRC内容赋给DST
注意:
存储器操作数之间不能直接传送
立即数不能直接传送段寄存器
段寄存器之间不能直接传送
CS只可以作为源操作数
源操作数和目的操作数的宽度必须相同
入栈指令(PUSH)
格式 PUSH src
操作过程分两步完成:
出栈指令(POP)
格式 POP dst;
操作:
1.(dst)<-((SP)+1, (SP))
2.(SP) <-(SP) + 2
功能:把Sp所执行的堆栈顶部的一个字送入目的地址,同时进行修改堆栈指针。
堆栈用途:
1.存放寄存器或存储器中暂时不使用的数据,再使用这些数据时可方便地将其弹出。
2.调用子程序或发生中断时要保护断点信息(入栈),子程序或中断返回时恢复断点信息(出栈)
断点信息:程序断点地址、标志寄存器及其它能被子程序使用和改变的寄存器。
注意:
1.堆栈操作都按字操作;
2.PUSH、POP指令的操作数可以是CPU内部寄存器或存储单元;
3.PUSH CS 合法,POP CS 非法;
4.执行PUSH指令,(SP)-2 ->(SP),低字节放在低地址,高字节放在高地址;
5.SP总是指向栈顶;
6.堆栈最大容量即为SP的初值与SS之差。
3)交换指令(XCHG)
格式:XCHG dst,src ; (dst)<->(src)
可以实现:寄存器之间、寄存器和存储器之间
注意:
存储器之间不能直接交换
段寄存器不能作为操作数
运行字或字节操作。
累加器专用传送指令;
1)输入指令(IN)
功能:用于CPU从外设端口接收数据
具体形式:
IN AL,data8; 从8位端口地址输入一个字节
IN AX,data8; 从8位端口地址输入一个字
IN AL,DX; 从16位端口地址输入一个字节
IN AX,DX; 从16位端口地址输入一个字
2)输出指令(OUT)
功能:用于CPU向外设端口发送数据
具体形式:
OUT data8,AL; 向8位端口地址输出一个字节
OUT data8,AX; 向8位端口地址输出一个字
OUT DX,AL; 向16位端口地址输出一个字节
OUT DX,AX; 向16位端口地址输出一个字
地址传送指令;
1)LEA (Load Effective Address)
格式: LEA reg16,mem
reg16---16位通用寄存器;
mem---存储单元;
功能:将源操作数的偏移地址传送到目的操作数
注意:源操作数必须以寄存器间接寻址、变址寻址、基址加变址寻址等方式表示的存储器操作数;
目的操作数位一个16位的通用寄存器。
2)LDS
格式:LDS reg16,mem;
功能:把源操作数指定的4个相继字节的数据分别送指令指定的寄存器及DS寄存器中。
(reg16) <- (mem)
(DS) <- ((mem) + 2)
3)LES
标志传送指令
1)LAHF(Load AH into flags)
格式:LAHF;
功能:标志寄存器低八位 -> (AH)
2)SAHF(Store AH into flags)
格式:SAHF
功能:(AH)送标志寄存器低八位
3)PUSHF (Push Flags)
格式:PUSHF;
功能:标志进栈
4)POPF (Pop Flags)
格式:POPF
功能:标志出栈
算术运算指令
包括:加法指令、减法指令、乘法指令、除法指令
1.加法指令
8086具有5条加法指令:
4、除法指令
1)无符号除法(DIV)
2)带符号除法(IDIV)
3)字节扩展指令(CBW)
4)字扩展指令( CWD
5、十进制调整指令(略)
共六条
位操作类指令
1)逻辑运算指令
?AND逻辑“与”指令
?TEST测试指令
?OR逻辑“或”指令
?XOR(eXclusive OR)逻辑“异或”指令
?NOT逻辑“非”指令
2)移位指令
共有以下8条
?SAL (Shift Arithmetic Left)算术左移
?SAR (Shiftarithmeticright)算术右移
?SHL (Shift logical left)逻辑左移
?SHR (Shiftlogicalright)逻辑右移
?ROL (Rotateleft)循环左移
?ROR (Rotateright)循环右移
?RCL (Rotateleftwith carry)带进位循环左移
?RCR (Rotateright withcarry)带进位循环右移
ROL:循环左移,高位到低位并送CF
ROR:循环右移,低位到高位并送CF
RCL:循环左移,进位值(原CF)到低位,高位进CF
RCR:循环右移,进位值(原CF)到高位,低位进CF
“串”就是内存中一段地址相连的字节或字;
?串操作,也叫数据块操作;
?可实现存储器数据间的直接传送;
?8086有5种基本串操作:B/W 字节/字
MOVS(Move string)串传送指令
CMPS(Compare string)串比较指令
SCAS(Scan string)串扫描指令
LODS(Load from string)取串指令
STOS (Store in to string)存串指令
(一)标志处理指令
?CLC (Clearcarryflag)清C标志
?STC(Setcarryflag )置C标志
?CMC(Complementcarryflag)对C求反
?CLD(Cleardirectionflag)清D标志
?STD(Setdirectionflag)置D标志
?CLI(Clearinterruptflag)清I标志
?STI (Setinterruptenableflag)置I标志
(二)其他处理机控制指令
?NOP(Nooperation)空操作
?HLT(Halt) CPU暂停状态
?WAITCPU等待状态
?ESC交权
?LOCK(Lockbus)总线锁定
指令REPE、REPZ和REPNE、REPNZ
无条件转移 JMP
有条件转移
过程(子过程)调用命令
CALL RET
循环控制指令
无条件循环 LOOP 语句标号 判断CX值是否为0
条件循环
LOOPZ/LOOPE 语句标号
LOOPNZ/LOOPNE 语句标号
中断指令
INT n n--中断号,0~255
中断返回 IRET
描述机器语言指令中,指定要执行某种操作的机器码。
OpCode与汇编指令的关系:
原文:https://www.cnblogs.com/yongchao/p/13324780.html