8086汇编基础知识总结 一、寄存器 1、4个数据寄存器(16位): AX(AH、AL) BX(BH、BL):常用作基数寄存器(即数据段的偏移地址寄存器) CX(CH、CL) DX(DH、DL) 2、指针寄存器 BP:基数指针寄存器,用作堆栈段的偏移地址寄存器 SP:堆栈指针寄存器,用于堆栈段的偏移地址寄存器 3、变址寄存器 SI:源变址寄存器,与BX功能相近,但更常用于变址寻址 DI:目的变址寄存器,与BX功能相近,但更常用于变址寻址 4、4个段寄存器 CS:代码段寄存器,存放代码段的段地址DS:数据段寄存器,存放数据段的段地址SS:堆栈段寄存器,存放堆栈段的段地址ES:附加数据段寄存器,当DS被占用后,可以另外使用ES来充当另外一个数据段的寄存器 5、其他 IP:指令指针寄存器(用作代码段的偏移地址寄存器) 6、状态标志寄存器 16位,有9个标志,见下文标志寄存器部分。 7、附:代码段、数据段、堆栈段 CS:IP(即物理地址为CSx16+IP)指向的指令即为当前正要执行的指令。 DS:BP(或DS:BX)指向的数据段,为当前可以读取的数据段 SS:SP指向当前正在读取的堆栈段地址。SS:SP指向的是栈顶素。 8、附:未显式给出段寄存器时的默认段寄存器 含有BX、DI、SI的寻址,默认段寄存器为DS 含有BP的寻址(同时含有BP和BX/SI/SI也属于这种情况),默认段寄存器位SS 二、8086执行指令的过程 从CS:IP指向的内存单读取指令,读到指令缓冲器中。IP=IP+指令的长度,指向下一条指令.执行指令,转到步骤1。 三、8086PC中内存的存储方式 1、8086对字的存储方式 8086的一个内存单为8位,1字节。对于一个字,8086采用小端模式(little-endian)在内存中存储,即一个字的高字节放到高地址,低字节放到低地址。 2、8086的物理地址 8086CPU有20位地址总线,16位数据总线。 8086的20位物理地址通过16位的段地址和16位的偏移地址合成,公式如下:
四、基本汇编指令 1、数据传送指令 (1)MOV——移动指令 MOV指令用来完成数据移动操作 MOV指令可以完成的9种操作:通用寄存器–>通用寄存器立即数–>通用寄存器立即数–>内存内存–>通用寄存器:MOV AX,DS:[BX]通用寄存器–>内存段寄存器(CS/IP除外)–>内存内存–>段寄存器(CS/IP除外)段寄存器(CS/IP除外)–>通用寄存器通用寄存器–>段寄存器(CS/IP除外) MOV指令不能修改CS/IP的内容 不能直接把立即数放到段寄存器中 (2)PUSH、POP——入栈、出栈指令 入栈和出栈操作均只能以字为单位进行。 栈的格式:栈顶:低地址栈底:高地址 PUSH AX操作的含义:SP=SP-2,栈顶指针空出一个字单位将AX的内容放到SS:SP指向的单(一个字)中,SS:SP重新指向栈顶 POP AX操作的含义:将SS:SP指向的单(一个字)内容送到AX中SP=SP+2,栈顶指针向下移动一个字单位 PUSH、POP支持的操作:PUSH/POP 通用寄存器PUSH/POP 段寄存器PUSH/POP 内存单 (3)PUSHF、POPF——标志寄存器入栈、出栈指令 PUSHF——将标志寄存器的值压入栈中 POPF——从栈中弹出数据,送到标志寄存器中 2、算术运算指令 (1)ADD——加指令 加指令把右边的数加到左边的数中 其含义为(dest)=(dest)+(src) 可以完成的操作ADD 通用寄存器,数据ADD 通用寄存器,通用寄存器ADD 通用寄存器,内存ADD 内存,通用寄存器ADD指令不能对段寄存器操作 (2)ADC——带进位加法指令 ADC指令会在执行加法时将CF位的进位值加上 其含义为:(dest)=(dest)+(src)+CF (3)INC指令——自加1指令 ,即将BX的内容自加1 (4)SUB——减指令 减指令从左边的数中减去右边的数 可以完成的操作SUB 通用寄存器,数据SUB 通用寄存器,通用寄存器SUB 通用寄存器,内存SUB 内存,通用寄存器 SUB指令不能对段寄存器操作 (5)SBB——带借位减指令 SBB指令会在执行减法时将CF位的借位值减去 其含义为:(dest)=(dest)-(src)-CF (6)DEC———自减1指令 ,即将BX的内容自减1 (7)DIV——除法指令 被除数/除数=商 除数:可以为8位或者16位,放在寄存器或者内存单中,在指令的操作数中显式给出。 被除数:根据除数的位数动态调整:如果除数为8位,则被除数为16位,需提前放在AX中,不用在指令中给出如果除数为16位,则被除数为32位,需提前放在DX(高16位)、AX(低16位)中,不需要在指令中给出 商:如果除数为8位,则商将放到AL中,余数将放到AH中如果除数为16位,则商将放到AX中,余数将放到DX中 (8)MUL——乘法指令 两个数相乘,要么都是8位,要么都是16位。 如果是8位一个乘数需要提前放到AL中,无需在指令中给出另一个乘数可以放到8位寄存器或者内存单中,需在指令中给出结果默认放到AX中 如果是16位一个乘数需要提前放到AX中,无需再指令中给出另一个乘数可以放到16位寄存器或者内存单中,需在指令中给出结果默认高位放到DX中,低位放到AX中 (9)CMP——比较指令 执行
的运算,但不保留运算结果,只是根据运算结果对相应的标志寄存器进行置位 3、逻辑指令 (1)AND、OR、NOT、XOR、TEST——与、或、非、异或等指令 AND AL,BL:将BL与AL的值进行按位与运算,结果存放到AL中OR AL,BL:将BL与AL的值进行按位或运算,结果存放到BL中XOR AL,BL:将BL与AL的值进行按位异或运算,结果存放到BL中NOT AL:对AL各位取反,不改变标志寄存器的值TEST AL,BL:将BL与AL的值进行按位与运算,不保存运算结果,只改变标志寄存器。两个操作数不能同时为内存单,不能为段寄存器除了NOT,其他指令都会修改标志寄存器 (2)SHL、SHR——逻辑移位指令 的功能:对寄存器/内存单的数据进行向左移位最高位移出去的一位放到CF中最低位缺失的位用0补充 的功能:对寄存器/内存单的数据进行向右移位最低位移出去的一位放到CF中最高位缺失的位用0补充如果移动位数大于1,则需要把移动位数放到CL寄存器中 4、转移指令 (1)JMP——无条件跳转指令 JMP指令用来修改CS和IP寄存器的值,即实现指令执行位置的跳转功能 JMP指令的几种形式: 段内短转移 :功能为(IP)=(IP)+转移距离(标号距离当前指令的距离,8位,因为是段内短转移) 段内近转移 :功能为(IP)=(IP)+转移距离(标号距离当前指令的距离,16位,因为是段内短转移) 段间转移(远转移) :功能为(CS)=所在段的段地址;(IP)=标号在段中的偏移地址 地址在寄存器中的转移 :功能为(IP)=(16位寄存器) 地址在内存的段内转移 (用[]的方式表示):功能为(IP)=该内存单地址处存放的一个字 地址在内存的段间转移 :功能为(CS)=(内存单地址+2)(即内存单地址高地址处存放的字);(IP)=(内存单地址)(即内存单地址低地址处存放的字) (2)有条件跳转指令合集 1)JCXZ 形式: 功能:如果(CX)=0,则跳转到标号处(即(IP)=(IP)+转移距离(8位));否则不跳转。所有的有条件跳转指令都只能进行短转移以下的有条件跳转指令根据标志位的情况置位(常与CMP指令配合,根据CMP指令无符号数的运算结果置位) 2)JE 形式: 功能:当标志位ZF=1时,转移到标号处 与CMP配合:当A=B时,跳转到标号处 3)JNE 形式: 功能:当标志位ZF=0时,转移到标号处 与CMP配合:当A!=B时,跳转到标号处 4)JB 形式:(B代表below) 功能:当标志位CF=1时,转移到标号处 与CMP配合:当A<B时,跳转到标号处(如果A<B,则A-B有借位,于是CF=1) 5)JNB 形式:(NB代表not below) 功能:当标志位CF=0时,转移到标号处 与CMP配合:当A>=B时,跳转到标号处(如果A>=B,则A-B无借位,于是CF=0) 6)JA 形式:(A代表above) 功能:当标志位CF=0且ZF=0时,转移到标号处 与CMP配合:当A>B时,跳转到标号处(如果A>B,则A-B无借位,于是CF=0;若A!=B,则ZF=0) 7)JNA 形式:(NA代表not above) 功能:当标志位CF=1或ZF=1时,转移到标号处 与CMP配合:当A<=B时,跳转到标号处(如果A<B,则A-B有借位,于是CF=1;若A=B,则CF=0且ZF=1。故合起来就是CF=1或ZF=1) (4)LOOP——循环指令 LOOP S的作用1.(CX)=(CX)-12.判断(CX)是否为0,若不为零,在跳转到标号S处((IP)=(IP)+转移距离(8位)),继续执行程序,否则退出循环所有的循环指令都只能进行短转移 (5)RET、RETF——返回指令 ——段内转移 功能:将栈顶数据弹出,然后以栈顶数据作为偏移地址进行段内跳转 详细操作:(IP)=((SS)*16+(SP))——利用栈顶素修改(IP),段内跳转(SP)=(SP)+2——弹出栈顶素 ——段间转移 功能:将栈顶的两个素先后弹出,弹出的第一个素作为跳转的偏移地址,弹出的第二个素作为跳转的段地址 详细操作:(IP)=((SS)*16+(SP))——利用栈顶素修改IP,获得偏移地址(SP)=(SP)+2——弹出栈顶素(CS)=((SS)*16+(SP))——利用新栈顶素修改CS,获得段地址(SP)=(SP)+2——再次弹出栈顶素 (6)CALL——调用指令 功能:将当前的IP值压入栈中,然后转到标号处执行指令 详细操作:(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(IP)——IP压入栈中(IP)=(IP)+偏移地址(16位)——跳转到标号处 功能:先将当前的段地址CS压入栈中,然后将当前的偏移地址IP压入到栈中。最后把CS和IP修改为标号的段地址和偏移地址,实现段间转移 详细操作:(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(CS)——CS压入栈中(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(IP)——IP压入栈中(CS)=标号所在段的段地址(IP)=标号在段中的偏移地址 功能:将当前的IP值压入栈中,然后转到寄存器指出的偏移地址处执行指令 详细操作:(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(IP)——IP压入栈中(IP)=(寄存器)——跳转到寄存器偏移地址处 功能:将当前的IP值压入栈中,然后转到内存单指出的偏移地址处执行指令 详细操作:(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(IP)——IP压入栈中(IP)=(内存单)——跳转到内存单偏移地址处 功能:先将当前的段地址CS压入栈中,然后将当前的偏移地址IP压入到栈中。最后把CS改为内存单的高字,IP改为内存单的低字,实现段间转移 详细操作:(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(CS)——CS压入栈中(SP)=(SP)-2——栈顶空出一个素((SS)*16+(SP))=(IP)——IP压入栈中(CS)=(内存单的高字)(IP)=(内存单的低字) 5、串操作指令 (1)MOVSB——字节串传送指令 功能:将DS:SI指向的内存单的一个字节的数据送入ES:DI指向的内存单中。然后如果DF=0,则SI自增1,DI自增1;如果DF=1,则SI自减1,DI自减1 详细操作:((ES)*16+(DI))=((DS)*16+(SI))(字节)如果DF=0,则(SI)=(SI)+1,(DI)=(DI)+1如果DF=1,则(SI)=(SI)-1,(DI)=(DI)-1 (2)MOVSW——字串传送指令 功能:将DS:SI指向的内存单的一个字的数据送入ES:DI指向的内存单中。然后如果DF=0,则SI自增2,DI自增2;如果DF=1,则SI自减2,DI自减2 详细操作:((ES)*16+(DI))=((DS)*16+(SI))(字)如果DF=0,则(SI)=(SI)+2,(DI)=(DI)+2如果DF=1,则(SI)=(SI)-2,(DI)=(DI)-2 (3)REP——重复指令(与串操作指令配合使用) REP指令要与MOVSB或者MOVSW配合使用,如下: 功能:重复执行MOVSB/MOVSW指令,每执行一次,CX减1。直到减到0,停止重复。以上指令等价于: REP实现了对于CX个连续单位(字节/字)的串操作,需要提前对DF位和CX进行合理设置DF提供方向信息,CX提供长度信息 (4)CLD/STD——DF方向标志位置位指令 CLD——将DF清0 STD——将DF置1 6、中断处理指令 (1)IRET——中断返回指令 IRET的功能为,先从栈中弹出一个字到IP中,然后再从栈中弹出一个字到CS中,最后从栈中弹出一个字到标志寄存器中。 相当于 一般将IRET放到中断程序的最后,表示退出中断程序,返回到原来程序中继续执行。 (2)INT——中断调用指令 表示引发N号中断,N为中断类型码。整个中断过程如下:取中断类型码N标志寄存器入栈,设置IF=0,TF=0CS,IP先后入栈(IP)=(N* 4),(CS)=(N* 4+2),即跳转到中断向量表指出的中断程序处执行。 在AH寄存器中需提前存放中断调用的子程序号INT与IRET配合,类似于CALL与RET配合 (3)STI/SLI——IF位置位指令 STI——设置IF=1 CLI——设置IF=0 (4)INTO——4号中断调用指令 如果OF=1,则相当于,调用溢出中断。如果OF=0,则什么都不做。 7、端口(I/O)操作指令 IN指令为从端口读入数据指令 OUT指令为从寄存器输出到端口的指令 端口号的范围只能是0~65535 当端口号为0~255时表示从20H端口读入一个字节到AL中表示把AL的值写入到20H端口 当端口号为256~65535时需要先把端口号放到DX中,然后表示从DX端口读入一个字节到AL中表示把AL的值写入到DX端口 IN/OUT指令只能使用AX或AL来存放读出或写入的数据,8位数据用AL,16位数据用AX 五、中断及中断过程 1、中断向量表 中断向量表中存放着每个中断类型码对应的中断程序入口地址。一个入口地址(中断描述符)包含4字节,前两字节为偏移地址,将被放到IP中;后两字节为段地址,将被放到CS中。将所有的入口地址以中断类型码为顺序排列为一张表,即为中断向量表。 中断向量表常存放在内存的开头,从0000:0000开始。 2、中断的过程(INTR请求) 外设通过总线向CPU发送中断请求,CPU接受到INTR信号,且如果IF=1,则响应中断通过中断响应信号INTA(非),给出两个负脉冲。第一个负脉冲通知外设已受理中断。在第二个负脉冲后,外设通过低8位数据总线,发出中断类型码。CPU收到后,对其进行暂存保护现场:将标志寄存器的值入栈避免冲突:将现在标志寄存器的TF、IF设为0保护现场:将CS、IP先后入栈根据中断类型码N,在中断向量表中读取对应的中断程序入口地址,并存放到IP和CS中。(IP)=(N* 4),(CS)=(N* 4+2) 3、外中断 (1)可屏蔽中断 由外设通过端口发出的中断类型之一,当IF=0时,可以屏蔽该中断。 其中断过程与内中断基本一致。 (2)不可屏蔽中断 CPU不可屏蔽、必须响应的外中断,中断类型码固定为2,无需取中断类型码。 六、标志寄存器 8086的标志寄存器有16位,其中有9位是有用的,称为9个标志。 1、ZF标志位——zero flag零标志位 相关指令执行后,如果结果位0,则ZF=1;否则ZF=0 2、PF标志位——parity flag奇偶标志位 相关指令执行后,如果结果中1的个数为偶数,则PF=1;如果是奇数,则PF=0 3、SF标志位——signal flag符号标志位 相关指令执行后,如果结果为负数(即结果的最高位为1),则SP=1;如果结果为正数(即结果的最高位为0),则SP=0在计算机中,不对有符号数和无符号数进行区分,计算机统一当作无符号数进行运算(不管符号位),结果根据需求人为地解读成有符号数或者无符号数如果要把结果解读成无符号数,则SF位是没有用的;如果要把结果解读成有符号数,则SF位有用。SF一直等于结果的最高位。 4、CF标志位——carry flag进位标志位 在相关指令执行后,在进行无符号运算时,如果加法有进位、或者减法有借位,则CF=1;否则CF=0注意:这里的加减运算完全按照无符号数规则进行运算,不管符号位,算出多少就是多少 5、OF标志位——overflow flag溢出标志位 在相关指令执行后,在进行有符号运算时,如果有溢出(8位有符号运算超出了-128~127的范围,16位有符号数运算超出了-32768~32767的范围。或者两个正数加出了负数,两个负数加出了正数),则OF=1;否则OF=0 判断溢出的方法(方法1):(方法1)对需要运算的两个操作数当作无符号数进行简单加减运算,如果两个操作数的最高位均为1,且运算结果最高位为0;或者两个操作数的最高位均为0,且运算结果最高位为1,则发生了溢出,OF=1;否则OF=0(方法2)如果两个待运算的操作数的最高位为一0一1(一正一负),则需要用此方法。首先将待运算的两个操作数当作补码,还原为两个有符号原码(如果是正数,则补码就是原码;如果是负数,最高符号位不变,其他位取反,然后加1),然后将两个有符号原码化为十进制,进行带符号的运算,查看运算结果。如果运算结果不在
(8位运算)或
(16位运算)范围内,则发生了溢出,OF=1,否则OF=0 6、DF标志位——direction flag方向标志位 在串操作中,指示串操作方向的标志位。 如果DF=0,则SI、DI在串操作后自增 如果DF=1,则SI、DI在串操作后自减 7、TF标志位——Tracking flag跟踪标志位 用于单步跟踪调试的标志位 如果TF=1,则CPU在每执行完一条指令后就触发单步中断 如果TF=0,则不会单步中断。8086要求在进入中断处理程序之前,把TF设为0,避免反复调用导致死循环。 8、IF标志位——Interruption enabled flag中断允许标志位 当IF=0时,不响应可屏蔽中断 当IF=1时,响应可屏蔽中断 六、寻址方式 摘自王爽汇编语言
七、MASM汇编的基本语法 1、简化段MASM程序的基本结构 2、几个重要规则 在简化段中,程序加载后,从DS:0开始为存储的整个MASM程序(包含代码段、数据段、堆栈段),其中前面的256个字节为PSP,因此真正的程序位于CS:0处(包含代码段、数据段、堆栈段,与我们定义的顺序前后有关),其中CS=DS+10H。 我们在定义ASSUME CS:CODE,DS:DATA后,并不意味着CS中存储了CODE段的段地址,DS存储了DATA段的段地址。ASSUME知识将段和寄存器关联起来。 各个段的段名,如CODE、DATA、STACK等本身即为该段的段地址 在写汇编程序时,需要首先完成的步骤:初始化CS:IP:使用START: END START标号对程序的起始位置进行定义初始化DS:BX:使用MOV AX,DATA MOV DS,AX MOV BX,0等代码对数据段的位置进行定义初始化SS:SP:使用MOV AX,STACK MOV SS,AX MOV SP,…,对堆栈段的位置进行定义,使得SS:SP指向堆栈的栈顶。 3、伪指令和操作符 以下定义数据在内存中的存放方式均遵循小端(little-endian)方式DW:以字为单位在内存中定义数据DB:以字节为单位在内存中定义数据,也可以定义字符串,需要拿单引号将字符串包起来,每一个字符即为一个ASCII码字节。DD:以双字为单位在内存中定义数据WORD/BYTE PTR:指明内存单操作数的长度,WORD表示长度为字,BYTE表示长度为字节。DUP:用来定义重复数据,如:即表示OFFSET:取标号的偏移地址。如:相当于把标号S的偏移地址放到AX寄存器中。 4、其他语法细则 汇编程序中,数据不能以字母开头,如A123H必须写为0A123H在需要暂存数据时(当寄存器数量不够时),常用堆栈来暂存8086CPU中,只有BX、SI、DI、BP可以用来进行寻址编译器可以直接处理简单的加减乘除表达式,比如5-2+3可以作为操作数出现在汇编程序中
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/75015.html