汇编部分总结

快考试了 , 写的汇编一点指令

汇编总结

标志位

标志位简介:

标志寄存器,又称程序状态寄存器(它的内容是Program Status Word,PSW).这是一个存放条件码标志,控制标志和系统标志的寄存器.

image-20210102163220609

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

image-20210102163756031

寻址方式

立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址、相对基址变址寻址、隐含寻址。

指令

一条指令通常由两个部分组成:

  • 第一部分为操作码(指令码)用于指出指令要进行何种操作;
  • 另一部分是指令操作的对象,称为操作码;

image-20210102164230959

8086 指令的长度在 1~7个字节之间。操作码占一个字节或两个字节。
指令的长度主要决定于操作数的个数及其采用的寻址方式。

指令在格式上就有以下3种形式:

  • 零操作数指令,指令在形式上只有操作码,操作数是隐含存在的;
  • 单操作数指令,指令中仅给出一个操作数,另一个操作数隐含存在;
  • 双操作数指令,指令中给出一个目标操作数,一个源操作数;

指令中的操作数类型

8086指令中的操作数主要有3种类型:立即数操作数、寄存器操作数、存储器操作数;

  • 立即数操作数:
    具有固定数值的操作数,即常数;在指令中,立即数操作数只能用作源操作数,而不能用作目标操作数;
  • 寄存器操作数:
    8086CPU 的 8个通用寄存器和 4个段寄存器可以作为指令中的寄存器操作数,可作为源操作数和目标操作数;通用寄存器存放参加运算的数据或数据所在存储器单元的偏移地址;段寄存器存放当前操作数的段基地址;
  • 存储器操作数:
    存储器操作数是指参加运算的数据,存放在内存中的,可作为源操作数、目标操作数;

指令的执行时间

一条指令的执行时间应包括 :取指令、取操作数、执行指令、传送结果;

三种类型的操作数中,寄存器操作数的指令执行速度最快,立即数操作数次之,存储器操作数指令的执行速度最慢;

寻址方式,是指获得操作数所在的地址的方法。一般将寻址方式分为两种:

  • 寻找操作数的地址;
  • 寻找要执行的下一条指令的地址;

@1 立即寻址

1
2
3
指令格式:
MOV AX , 1234H
12

立即数主要是给寄存器赋初始值;

立即寻址方式只针对源操作数,此时源操作数是一个立即数,它作为指令的一部分,紧跟在指令的操作码之后、存放于内存的代码段中;

立即数:通常把在立即寻址方式指令中给出的数称为立即数。立即数可以是8位、16位或32位,该数值紧跟在操作码之后。如果立即数为16位或32位,那么,它将按“高高低低”的原则进行存储。

@2 直接寻址

1
2
3
指令格式:
MOV AX ,[1234H]
12

直接寻址方式表示参加运算的数据存放在内存中,指令中给出的是数据存放的偏移地址;

注意:
直接寻址指令中的数值是操作数的 16 位偏移地址,而不是数据本身,为了区分,指令系统规定偏移地址必须用方括号括起来;在此,可以理解为 C语言的 指针符号 ——解析指针,将其类比为解析其中的偏移地址;

@3 寄存器寻址

1
2
3
指令格式:
MOV SI , AX
12

在寄存器寻址方式下,指令的操作数为 CPU 的内部寄存器,可以是数据寄存器(8位或16位),也可以是地址指针、变址寄存器、段寄存器;

image-20210102164532414

采用寄存器寻址方式,虽然指令操作码在代码段中,但操作数在内部寄存器中,指令执行时不必通过访问内存就可以取到操作数,故执行速度较快;

@4 寄存器间接寻址

1
2
3
指令格式:
MOV AX , [SI]
12

寄存器间接寻址是用寄存器的内容表示操作数的偏移地址。

寄存器间接寻址方式中存放操作数偏移地址的寄存器只允许是 SI、DI、BX、BP;
选择不同的间接寻址寄存器涉及的段寄存器不同。在默认情况下:

  • 选择SI、DI、BX 作间接寻址寄存器时,操作数在数据段,段基地址由 DS决定;
  • 选择 BP 作间接寻址寄存器时,则操作数在堆栈段,段基地址由 SS 决定;

@5 寄存器相对寻址

1
2
3
指令格式:
MOV BX , [BP - 8]
12

在寄存器相对寻址方式中,操作数在内存中的偏移地址由间接地址寄存器的内容加上指令中给出的一个 8 位或 16 位的位偏移量组成;

image-20210102164640754

如果有效地址超过 64KB ,则取64KB 的模;

@6 基址 - 变址 寻址

1
2
3
指令格式:
MOV AX , [BX - SI]
12

基址 - 变址寻址方式由一个基址寄存器(BX 或 BP)的内容和一个变址寄存器(SI 或 DI)的内容相加而形成操作数的偏移地址;

image-20210102164657903

在默认情况下

  • 指令中若用 BX 作基址寄存器,则段地址在 DS 中;
  • 指令中若用 BP 作基址寄存器,则段地址在 SS 中;

@7 基址 - 变址 - 相对寻址

1
2
3
指令格式:
MOV AX , [BX + DI +5]
12

基址 - 变址 - 相对寻址方式是 基址 - 变址寻址方式的扩充;

image-20210102164714313

指令中指定一个基址寄存器和一个变址寄存器,还给出一个 8位 或 16位 的位移量,将三者相加就得到操作数的偏移地址;

使用这种寻址方式可以很方便地访问二维数组;
与寄存器间接寻址方式类似,基址 - 变址 - 相对寻址 指令也可以表示成多种形式;
同样地,基址 - 变址 - 相对寻址 也不允许在指令中同时出现两个基址寄存器或两个变址寄存器;

@8 隐含寻址

有些指令的操作码中不仅包含了操作的性质,还隐含了部分操作数的地址;这种将一个操作数隐含在指令码中的寻址方式就是隐含寻址;

相关指令

基本指令

https://blog.csdn.net/wa_junye/article/details/106307500

该链接 有大量的基本指令

mul指令

实现 AL 乘以 BL

1
2
3
4
mov al, 5h
mov bl, 10h
mul bl ; AX = 0050h, CF = 0
由于 AH(乘积的高半部分)等于零,因此进位标志位被清除(CF=0)

实现 16 位值 2000h 乘以 0100h

1
2
3
4
5
6
7
.data
val1 WORD 2000h
val2 WORD 0l00h
.code
mov ax, val1 ; AX = 2000h
mul val2 ; DX:AX = 00200000h, CF = 1
由于乘积的高半部分(存放于 DX)不等于零,因此进位标志位被置 1:

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
2
3
mov ax,17 //在DosBox下用Debug,好像只能使用十六进制,不能加后缀h
mov bl,3
div bl

难点指令

image-20210102170302273

PUSHF 指令

( PUSH the Flags) 标志进栈指令 ( 不影响标志位寄存器

标志寄存器的值压入堆栈顶部, 同时栈指针SP值减2

执行操作: SP=SP-1,(SP)=PSW的高8位, SP=SP-1, (SP)=PSW的低8位

POPF 指令

( POP the Flags ) 标志出栈指令 ( 影响标志位寄存器

POPF 与PUSHF相反, 从堆栈的顶部弹出两个字节送到PSW寄存器中, 同时堆栈指针值加2

这两条指令后面都不加东西,默认的操作对象是:所有的标志寄存器。

LAHF 指令

用于将标志寄存器的低八位送入AH,即将标志寄存器FLAGS中的SF、ZF、AF、PF、CF五个标志位分别传送到累加器AH的对应位(八位中有三位是无效的)( 不影响标志位寄存器

SAHF 指令

该指令将AH的字节内容传送入标志寄存器的低八位中,是LAHF指令的反操作。SAHF指令影响标志位,标志位的SF、ZF、AF、PF和AF将被修改成AH寄存器相对应位的状态,但其余位不变。

int/out 指令

读端口用IN指令,写端口用OUT指令。

1
2
3
4
5
6
7
8
9
10
例子如下:
  IN AL,21H;表示从21H端口读取一字节数据到AL
  IN AX,21H;表示从端口地址21H读取1字节数据到AL,从端口地址22H读取1字节到AH
  MOV DX,379H
  IN AL,DX ;从端口379H读取1字节到AL

  OUT 21H,AL;将AL的值写入21H端口
  OUT 21H,AX;将AX的值写入端口地址21H开始的连续两个字节。(port[21H]=AL,port[22h]=AH
  MOV DX,378H
  OUT DX,AX ;将AH和AL分别写入端口379H和378H

例题 用两种方法将字节数据43H从61H端口输出

方法一:(直接输出或称长格式)

1
2
MOV AL,43H
OUT 61H,AL

方法二:(间接输出或称短格式)

1
2
3
MOV  AL,43H
MOV DX,61H
OUT DX,AL

adc 指令

adc是带进位的加法指令,它利用了CF上记录的进位值

  • 指令格式:adc 操作对象1,操作对象2
  • 功能: 操作对象1 = 操作对象1 + 操作对象2 + CF

比如:计算1EF000H + 201000H,结果放在ax(高16位)和bx(低16位)中:

1
2
3
4
mov ax, 001EH
mov bx, 0F000H
add bx, 1000H
adc ax, 0020H

sbb 指令

sbb是借位减法指令,它利用了CF位上记录的借位值

  • 指令格式:sbb 操作对象1,操作对象2
  • 功能:操作对象1 = 操作对象1 - 操作对象2 - CF

比如:计算003E1000H - 00202000H,结果保存在ax,bx中

1
2
3
4
mov bx, 1000H
mov ax, 003EH
sub bx, 2000H
sbb ax, 0020H

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://blog.csdn.net/ly131420/article/details/8741220?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-1.control

推荐下面那个

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. 键盘输入一串字符,屏幕显示该字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Data  segment
A db 20, 0, 20 dup(‘$’)
Data ends
Code segment
Assume cs:code, ds:data
Start:
mov ax,data
Mov ds,ax
Lea dx,a ;键盘输入一串字符
Mov ah,10
Int 21h
Mov dl,0dh ;显示回车
Mov ah,2
Int 21h
Mov dl,0ah ;显示换行
Mov ah,2
Int 21h
Lea dx,a+2 ;屏幕输出一串字符
Mov ah,9
Int 21h
Mov ah,4ch
Int 21h
Code ends
End start

2.将一串字符中的小字字符全部转换成大写字符并输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Data  segment
A db 20, 0, 20 dup(‘$’)
alen db 0ffh,0
Data ends
Code segment
Assume cs:code, ds:data
Start:
mov ax,data
Mov ds,ax
Lea dx,a ;键盘输入一串字符
Mov ah,10
Int 21h
Mov dl,0dh ;显示回车
Mov ah,2
Int 21h
Mov dl,0ah ;显示换行
Mov ah,2
Int 21h

mov cl,alen+1
mov bx,2
s:
mov A,A[bx]
sub A,20h ;转大写字母
inc A
loop s

Lea dx,a+2 ;屏幕输出一串字符
Mov ah,9
Int 21h
Mov ah,4ch
Int 21h
Code ends
End start
  1. S=1+2+3+…+100 并输出结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
OUTP  MACRO  X
MOV CX, 0
MOV AX, X
AA1:INC CX
MOV DX, 0
MOV BX,10
DIV BX
PUSH DX
CMP AX,0
JNZ AA1
AA2:POP DX
OR DL, 30H
MOV AH,2
INT 21H
LOOP AA2
ENDM

DATA SEGMENT
S DW 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV CX,100
MOV S,0
MOV AX,1
A1:ADD S, AX
INC AX
LOOP A1
OUTP S
MOV AH,4CH
INT 21H
CODE ENDS
END START

5.S=1!+2!+3!+…5! 并输出结果

1
2
3
4
5
6
7
    MOV CX, 5
MOV AX, 1
MOV BX, 1
NEXT:MUL BX
ADD S, AX
INC BX
LOOP NEXT:

6.S=1^2+2^2+3^2+…+10^2 并输出结果

1
2
3
4
5
6
7
8
9
    MOV  S,0                                   
MOV CX,10
MOV AX, 1
MOV BX, 1
NEXT:MUL BX
ADD S, AX
INC BX
MOV AX, BX
LOOP NEXT

8.计算100及其以内奇数和与偶数和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;奇数和
MOV CX,50
MOV S, 0
MOV AX, 1
NEXT: ADD S, AX
ADD AX, 2
LOOP NEXT

;偶数和
MOV CX,50
MOV S, 0
MOV AX, 2
NEXT: ADD S, AX
ADD AX, 2
LOOP NEXT
  1. 计算 1234567-902368
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
DATA  SEGMENT              
A DB 7,6,5,4,3,2,1
B DB 8,6,3,2,0,9,0
C DB 7 dup(0)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV SI,0
CLC
MOV CX, 7
NEXT1:
MOV AL, A[SI]
SBB AL,B[SI]
AAS
MOV C[SI],AL
INC SI
LOOP NEXT1
MOV CX, 10
MOV SI,6
NEXT2:
MOV DL,C[SI]
OR DL,30H
MOV AH,2
INT 21
DEC SI
LOOP NEXT2
MOV AH,4CH
INT 21H
CODE ENDS
END START
Reward
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • © 2015-2021 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信