快考试了 , 写的汇编一点指令
汇编总结
标志位
标志位简介:
标志寄存器,又称程序状态寄存器(它的内容是Program Status Word,PSW).这是一个存放条件码标志,控制标志和系统标志的寄存器.
6个状态标志位
CF—进位标志,加法时的最高位(D7或D15)产生进位或减法时最高位出现借位,则CF=1,否则CF=0;
AF—辅助进位标志,供BCD码使用。当D3位出现进位或借位时AF=1,否则AF=0;
OF—溢出标志,带符号数进行算术运算时,其结果超出了8位或16位的表示范围,产生溢出,则OF=1,否则OF=0;
ZF—零标志,运算结果各位都为零,则ZF=1,否则ZF=0;
SF—符号标志,运算结果为负数时,即运算结果的最高位为1,则SF=1,否则SF=0;
PF—奇偶标志,反映操作结果中“1”的个数的情况,若有偶数个“1”,则PF=1,否则PF=0。
3个控制标志位
DF—方向标志,用来控制数据串操作指令的步进方向;
当设置DF=1时,将以递减顺序对数据串中的数据进行处理。当设置DF=0时,递增。
IF—中断允许标志,当设置IF=1,开中断,CPU可响应可屏蔽中断请求;当设置IF=0时,关中断,CPU不响应可屏蔽中断请求。
TF—陷阱标志,为程序调试而设的。当设置TF=1,CPU处于单步执行指令的方式;当设置TF=0时,CPU正常执行程序。
标志 | 值为1 | 值为0 |
---|---|---|
OF | OV | NV |
DF | DN | UP |
IF | EI | DI |
SF | NG | PL |
ZF | ZR | NZ |
AF | AC | NA |
PF | PE | PO |
CF | CY | NC |
寻址方式
立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址、相对基址变址寻址、隐含寻址。
指令
一条指令通常由两个部分组成:
- 第一部分为操作码(指令码)用于指出指令要进行何种操作;
- 另一部分是指令操作的对象,称为操作码;
8086 指令的长度在 1~7个字节之间。操作码占一个字节或两个字节。
指令的长度主要决定于操作数的个数及其采用的寻址方式。
指令在格式上就有以下3种形式:
- 零操作数指令,指令在形式上只有操作码,操作数是隐含存在的;
- 单操作数指令,指令中仅给出一个操作数,另一个操作数隐含存在;
- 双操作数指令,指令中给出一个目标操作数,一个源操作数;
指令中的操作数类型
8086指令中的操作数主要有3种类型:立即数操作数、寄存器操作数、存储器操作数;
- 立即数操作数:
具有固定数值的操作数,即常数;在指令中,立即数操作数只能用作源操作数,而不能用作目标操作数; - 寄存器操作数:
8086CPU 的 8个通用寄存器和 4个段寄存器可以作为指令中的寄存器操作数,可作为源操作数和目标操作数;通用寄存器存放参加运算的数据或数据所在存储器单元的偏移地址;段寄存器存放当前操作数的段基地址; - 存储器操作数:
存储器操作数是指参加运算的数据,存放在内存中的,可作为源操作数、目标操作数;
指令的执行时间
一条指令的执行时间应包括 :取指令、取操作数、执行指令、传送结果;
三种类型的操作数中,寄存器操作数的指令执行速度最快,立即数操作数次之,存储器操作数指令的执行速度最慢;
寻址方式,是指获得操作数所在的地址的方法。一般将寻址方式分为两种:
- 寻找操作数的地址;
- 寻找要执行的下一条指令的地址;
@1 立即寻址
1 | 指令格式: |
立即数主要是给寄存器赋初始值;
立即寻址方式只针对源操作数,此时源操作数是一个立即数,它作为指令的一部分,紧跟在指令的操作码之后、存放于内存的代码段中;
立即数:通常把在立即寻址方式指令中给出的数称为立即数。立即数可以是8位、16位或32位,该数值紧跟在操作码之后。如果立即数为16位或32位,那么,它将按“高高低低”的原则进行存储。
@2 直接寻址
1 | 指令格式: |
直接寻址方式表示参加运算的数据存放在内存中,指令中给出的是数据存放的偏移地址;
注意:
直接寻址指令中的数值是操作数的 16 位偏移地址,而不是数据本身,为了区分,指令系统规定偏移地址必须用方括号括起来;在此,可以理解为 C语言的 指针符号 ——解析指针,将其类比为解析其中的偏移地址;
@3 寄存器寻址
1 | 指令格式: |
在寄存器寻址方式下,指令的操作数为 CPU 的内部寄存器,可以是数据寄存器(8位或16位),也可以是地址指针、变址寄存器、段寄存器;
采用寄存器寻址方式,虽然指令操作码在代码段中,但操作数在内部寄存器中,指令执行时不必通过访问内存就可以取到操作数,故执行速度较快;
@4 寄存器间接寻址
1 | 指令格式: |
寄存器间接寻址是用寄存器的内容表示操作数的偏移地址。
寄存器间接寻址方式中存放操作数偏移地址的寄存器只允许是 SI、DI、BX、BP;
选择不同的间接寻址寄存器涉及的段寄存器不同。在默认情况下:
- 选择SI、DI、BX 作间接寻址寄存器时,操作数在数据段,段基地址由 DS决定;
- 选择 BP 作间接寻址寄存器时,则操作数在堆栈段,段基地址由 SS 决定;
@5 寄存器相对寻址
1 | 指令格式: |
在寄存器相对寻址方式中,操作数在内存中的偏移地址由间接地址寄存器的内容加上指令中给出的一个 8 位或 16 位的位偏移量组成;
如果有效地址超过 64KB ,则取64KB 的模;
@6 基址 - 变址 寻址
1 | 指令格式: |
基址 - 变址寻址方式由一个基址寄存器(BX 或 BP)的内容和一个变址寄存器(SI 或 DI)的内容相加而形成操作数的偏移地址;
在默认情况下
- 指令中若用 BX 作基址寄存器,则段地址在 DS 中;
- 指令中若用 BP 作基址寄存器,则段地址在 SS 中;
@7 基址 - 变址 - 相对寻址
1 | 指令格式: |
基址 - 变址 - 相对寻址方式是 基址 - 变址寻址方式的扩充;
指令中指定一个基址寄存器和一个变址寄存器,还给出一个 8位 或 16位 的位移量,将三者相加就得到操作数的偏移地址;
使用这种寻址方式可以很方便地访问二维数组;
与寄存器间接寻址方式类似,基址 - 变址 - 相对寻址 指令也可以表示成多种形式;
同样地,基址 - 变址 - 相对寻址 也不允许在指令中同时出现两个基址寄存器或两个变址寄存器;
@8 隐含寻址
有些指令的操作码中不仅包含了操作的性质,还隐含了部分操作数的地址;这种将一个操作数隐含在指令码中的寻址方式就是隐含寻址;
相关指令
基本指令
https://blog.csdn.net/wa_junye/article/details/106307500
该链接 有大量的基本指令
mul指令
实现 AL 乘以 BL
1 | mov al, 5h |
实现 16 位值 2000h 乘以 0100h
1 | .data |
div指令
div指令使用感觉比较麻烦,需要注意几点:
1:除数为8位或者16位(即字节型或字型),在寄存器或内存单元中
2: 被除数在AX 或者 AX和DX中( 注意,后面是AX和DX,AX存放低16位,DX存放高16位)
除数 | 被除数 |
---|---|
8位 | 16位 |
16位 | 32位(AX和DX) |
当除数为8位时,商存放在AL寄存器中,余数存放在AH寄存器中,
当除数为16位时,商在AX中,余数在DX中
实现 16位除以8位的:
1 | mov ax,17 //在DosBox下用Debug,好像只能使用十六进制,不能加后缀h |
难点指令
PUSHF 指令
( PUSH the Flags) 标志进栈指令 ( 不影响标志位寄存器
将标志寄存器的值压入堆栈顶部, 同时栈指针SP值减2
执行操作: SP=SP-1,(SP)=PSW的高8位, SP=SP-1, (SP)=PSW的低8位
POPF 指令
( POP the Flags ) 标志出栈指令 ( 影响标志位寄存器
这两条指令后面都不加东西,默认的操作对象是:所有的标志寄存器。
LAHF 指令
用于将标志寄存器的低八位送入AH,即将标志寄存器FLAGS中的SF、ZF、AF、PF、CF五个标志位分别传送到累加器AH的对应位(八位中有三位是无效的)( 不影响标志位寄存器
SAHF 指令
该指令将AH的字节内容传送入标志寄存器的低八位中,是LAHF指令的反操作。SAHF指令影响标志位,标志位的SF、ZF、AF、PF和AF将被修改成AH寄存器相对应位的状态,但其余位不变。
int/out 指令
读端口用IN指令,写端口用OUT指令。
1 | 例子如下: |
例题 用两种方法将字节数据43H从61H端口输出
方法一:(直接输出或称长格式)
1 | MOV AL,43H |
方法二:(间接输出或称短格式)
1 | MOV AL,43H |
adc 指令
adc是带进位的加法指令,它利用了CF上记录的进位值
- 指令格式:adc 操作对象1,操作对象2
- 功能: 操作对象1 = 操作对象1 + 操作对象2 + CF
比如:计算1EF000H + 201000H,结果放在ax(高16位)和bx(低16位)中:
1 | mov ax, 001EH |
sbb 指令
sbb是借位减法指令,它利用了CF位上记录的借位值
- 指令格式:sbb 操作对象1,操作对象2
- 功能:操作对象1 = 操作对象1 - 操作对象2 - CF
比如:计算003E1000H - 00202000H,结果保存在ax,bx中
1 | mov bx, 1000H |
cmp 指令
cmp是比较指令,功能相当于减法指令,只是不保存结果。执行后,对标志寄存器产生影响
- cmp指令格式:cmp 操作对象1,操作对象2
- 功能:计算操作对象1 - 操作对象2,但不保存结果
通常与跳转指令搭配
XCHG 指令
交换指令XCHG是两个寄存器,寄存器和内存变量之间内容的交换指令,两个操作数的数据类型要相同,可以是一个字节,也可以是一个字,也可以是双字(不影响标志寄存器
XLAT 指令
把待查表格的一个字节内容送到AL累加器中。在执行该指令前,应将TABLE先送至BX寄存器中,然后将待查字节与其在表格中距表首地址位移量送AL,即AL<–((BX)+(AL)). 执行XLAT将使待查内容送到累加器
https://baike.baidu.com/item/XLAT%E6%8C%87%E4%BB%A4/4144842?fr=aladdin
CBW 指令
在8086中CBW指令将AL的最高有效位D7扩展至AH,
即:如果AL的最高有效位是0,则AH = 00;AL的最高有效位为1,则AH = FFH。AL不变。(即将AL的符号位移至AH)
CBW属符号扩展指令,它可以把8位扩展到16位,扩展前后两数的真值不变,主要用于数据类型不同时用符号扩展指令可以使得数据类型相同。
CWD 指令
CWD的作用是将带符号的16位整数(ax)转为32位的带符号位的整数(dx:ax),例如:ax=0xFFFE, 转为32位带符号位的整数时,dx=0xFFFF,AX=0XFFFE.又例如:ax=0x0002,转为带符号位的整数时dx=0x0000,ax=0x0002.
BCD码 指令
推荐下面那个
https://my.oschina.net/iwuyang/blog/198627
跳转指令
指 令 | 描 述 | 条 件 | 别 名 | 相 反 指 令 |
---|---|---|---|---|
JC | 如果进位位被置位则跳转 | 进位标志=1 | JB,JNAE | JNC |
JNC | 如果进位位没有置位则跳转 | 进位标志=0 | JNB,JAE | JC |
JZ | 如果0标志被置位则跳转 | 0标志=1 | JE | JNZ |
JNZ | 如果0标志没有置位则跳转 | 0标志=0 | JNE | JZ |
JS | 如果符号位被置位则跳转 | 符号标志=1 | JNS | |
JNS | 如果符号位没有被置位则跳转 | 符号标志=0 | JS | |
JO | 如果溢出标志置位则跳转 | 溢出标志=1 | JNO | |
JNO | 如果溢出标志没有置位则跳转 | 溢出标志=0 | JO | |
JP | 如果奇偶校验位被置位则跳转 | 奇偶校验标志=1 | JPE | JNP |
JPE | 如果奇偶校验位为偶校验则跳转 | 奇偶校验标志=1 | JP | JPO |
JNP | 如果奇偶校验位没有被置位则跳转 | 奇偶校验标志=0 | JPO | JP |
JPO | 如果奇偶校验位为奇校验则跳转 | 奇偶校验标志=0 | JNP | JPE |
使用无符号数比较的JCC指令
指 令 | 描 述 | 条 件 | 别 名 | 相反指令 |
---|---|---|---|---|
JA | 如果超过(>)则跳转 | 进位标志=0,0标志=0 | JNBE | JNA |
JNBE | 如果不低于或等于(不 <=)则跳转 | 进位标志=0,0标志=0 | JA | JBE |
JAE | 如果超过或等于(>=)则跳转 | 进位标志=0 | JNC,JNB | JNAE |
JNB | 如果不低于则跳转(不 <) | 进位标志=0 | JNC,JAE | JB |
JB | 如果低于(<)则跳转 | 进位标志=1 | JC,JNAE | JNB |
JNAE | 如果不超过或等于(不>=)则跳转 | 进位标志=1 | JC,JB | JAE |
JBE | 如果低于或等于(<=)则跳转 | 进位标志=1或0标志=1 | JNA | JNBE |
JNA | 如果不超过(不>)则跳转 | 进位标志=1或0标志=1 | JBE | JA |
JE | 如果相等(=)则跳转 | 0标志=1 | JZ | JNE |
JNE | 如果不相等(<>)则跳转 | 0标志=0 | JNZ | JE |
使用有符号数比较的JCC指令
指 令 | 描 述 | 条 件 | 别 名 | 相反指令 |
---|---|---|---|---|
JG | 如果大于(>)则跳转 | 符号标志=溢出标志或0标志=0 | JNLE | JNG |
JNLE | 如果小于或等于(<=)则跳转 | 符号标志=溢出标志或0标志=0 | JG | JLE |
JGE | 如果大于或等于(>=)则跳转 | 符号标志=溢出标志 | JNL | JGE |
JNL | 如果不小于(不<)则跳转 | 符号标志=溢出标志 | JGE | JL |
JL | 如果小于(<)则跳转 | 符号标志<>溢出标志 | JNGE | JNL |
JNGE | 如果大于或等于(>=)跳转 | 符号标志<>溢出标志 | JL | JGE |
JLE | 如果小于或等于(<=)跳转 | 符号标志<>溢出标志或0标志=1 | JNG | JNLE |
JNG | 如果不大于(不>)则跳转 | 符号标志<>溢出标志或0标志=1 | JLE | JG |
JE | 如果等于(=)则跳转 | 0标志=1 | JZ | JNE |
JNE | 如果不等于(<>)则跳转 | 0标志=0 | JNZ | JE |
串处理指令
https://blog.csdn.net/better0332/article/details/2293884
关键例题
- 键盘输入一串字符,屏幕显示该字符串
1 | Data segment |
2.将一串字符中的小字字符全部转换成大写字符并输出。
1 | Data segment |
- S=1+2+3+…+100 并输出结果
1 | OUTP MACRO X |
5.S=1!+2!+3!+…5! 并输出结果
1 | MOV CX, 5 |
6.S=1^2+2^2+3^2+…+10^2 并输出结果
1 | MOV S,0 |
8.计算100及其以内奇数和与偶数和
1 | ;奇数和 |
- 计算 1234567-902368
1 | DATA SEGMENT |