锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

[汇编原理 IBM-PC] 串循环指令/循环指令LOOP/子程序

时间:2022-08-16 10:30:02 tr35jbe0330电阻

串处理指令

前言

串处理指令一般与REP指令配合。 因为串操作指令实际上只反映在串上REP上

REP是前缀,但它不是伪指令,REP它具有特定的功能,可以判断CX是否为0还可以执行CX=CX-1
CX递减不影响标识位

CLD(CLear Directionflag)是清方向的标志位,即使用DF执行串操作时,值为0,地址以增加的方式变化,这很容易调整相关部分的当前指针。此指令和STD(SeT Direction flag)的执行结果相反,即置DF的值为1

串指令一般分为两类

1与REP 相配合的MOVS LODS STOS INS OUTS指令

格式一般为:REP 指令
执行操作:
1.先判断CX(计数寄存器)是否为0,如果为0,则退出循环
2.CX减一
3.执行MOVS等串指令
4.重复1~3的步骤

1.1 MOVS 串传送指令

常见格式:
1.MOVSB (字节操作) MOVSW(字操作)
实际执行的是

  • 1、将数据段DS源变址寄存器SI指向数据段的内容传送到 附加段ES目的变址寄存器附加附加段的内容当中
  • 2.按方向标记位置DF 相应修改 源变址寄存器SI 和目的变址寄存器 DI(也就是修改地址,准备下一次操作)
  • 3、DF=0:SI、DI增加1,DF=1:SI、DI减1(如果是字节操作,则相应增加2,减2)

REP MOVS 使用串传指令

  • 1.将数据段源串的第一个地址放入源变址寄存器中(如果方向相反,则放末地址)
  • 2.将要存储数据串的附加段的首地址放入目的变址寄存器中(相反方向,相同)
  • 3.将源串的长度放入计数寄存器(设置循环次数)CX)
  • 4、设置方向
    例题:
    3.70:
    数据段中有一个字符串,长度为17,需要送到附加段中的缓冲区
> data segment >   mess1 db 'personal computer $' > data ends >   >  extra segment >   mess2 db 17 dup(?) >  extra ends  >    >   code segment >   assume ds:data,es:extra >   mov ax,data >   mov ds,ax >     >   mov ax,extra >   mov es,as >   lea si,mess1 >   lea di,mess2 >   mov cx,17 >   cld >   rep movsb >    code ends 

1.2 STOS 存入串操作

STOS该指令通常用于初始化并且是初始化附加段)
常见格式
LODSB (字节操作) LODSW(字操作)
实际上操作的两个默认的寄存器是:AX与DI
执行操作如下:

  • 1.把AL(字节操作)/AX(字操作)内容存储在目的寄存器指向的附加部分的单元中
  • 2.根据方向标志位更改目的寄存器的地址

与REP连用的应用
例题
3.71 如果要将附加段的第五个字节缓冲区置为20H

MOV CX,5 MOV AL,20H MOV DI,0H CLD REP STOSB 

1.3 LODS从串取指令

常见格式:
LODSB (字节操作) LODSW(字操作)
两个默认寄存器位AX与SI
执行操作位置:

  • 1.将源变址寄存器指向的单元内容发送到AX/AL分别取决于字操作和字节操作
  • 2.根据方向标志和数据类型修改源变址寄存器的内容(即修改地址)

因为所有的操作都是传单元的AX/AL所以一般不和REP连用
总结:STOS和LODS都是与AX与寄存器有关STOS是存储到ES段中,因此相应的寄存器是DI(目的变址寄存器)LODS是取出,因此相应的寄存器是SI(源变址寄存器)

1.4 INS和OUTS

这两个与STOS/LODS与外部设备交换数据非常相似。
INSB 与INSW

  • 1、指令是把I/O空间的字节/字传输到附加段落的变址寄存器指向的存储单元
  • 2、根据DF数据类型修改目的的的值
    而使用DX存储端口号,相当于I/O空间的地址
    因此操作:((DX))–>((DI))
    再改变DI寄存器的内容

OUTSB OUTSW

  • 1.将源变址寄存器指向的数据段的字节/字单元发送到DX端口号的I/O空间中
  • 2、根据DF数据类型修改的值,SI的大小

2与REPZ/REPE 和REPNZ/REPNE联合工作的CMPS SCAS指令

REPZ/REPE:repeat while 相等或为0时
也就是重复串操作的条件除了CX不等于0,另外一个得满足的条件是ZF=1
执行的操作为:

  • 1、判断:若CX=0或者ZF=0(注意这里的ZF=0是不等于0.
  • 2、CX减1
  • 3、执行后面的串操作
  • 4、重复1~3

与REPE/REPZ和REPNE/REPNZ联合工作的串比较指令CMPS和SCAS

关键在于CX=0是退出条件,CX不能体现字符串比较出的结果,CX=0只能说明每一个都比完了,至于结果,结果唯一的条件就是ZF
执行的操作是先判断CX是否为0,ZF是否为0,CX=0,ZF=0两个条件满足一个就退出。否则继续向下,CX=CX-1,执行其后的串指令。
重复上述过程。
REPE和REPZ是完全相等的同义词!两者可以随意相互替换。REPE/REPZ——相等则重复

REP循环指令都是while-do,先判断条件再执行,并且cx的递减都不会影响标志位

在这里插入图片描述

2.1 CMPS 串比较指令

CMPSB CMPSW

  • 1.指令把源变址寄存器指向的数据段的一个字节/字单元与目的变址寄存器指向的附加段一个字节/字单元相减,但并不保存结果,只改变标志位
  • 2、根据DF与数据类型改变源变址寄存器和目的变址寄存器
    用源串中的一个字节(或者字)减去目的串中的一个字节(或者字)
    因为做了减法,结果很显然会对标志寄存器产生影响,如果结果为0,ZF标志位会等于1

2.2 SCAS 串扫描指令

与CMPS类似,只是CMPS是串之间的比较,而SCAS是一个串的扫描(比如寻找这个串的某个值),都是执行相减的操作

  • 1、指令将AL/AX的内容与目的变址寄存器指向的附加段的字节/字单元内容相减,同样不保存结果,只根据结果设置标志位
  • 2、根据DF和数据类型修改目的变址寄存器

2.3 CMPS/SCAS两个串指令与REPZ/REPE/REPNZ/REPNE结合,用来比较两个数据串或者从一个字符串中寻找一个指定的字符

LOOP循环指令

loop指令的格式是:loop 标号

cpu执行loop指令的时候,要进行两步操作

step 1:(cx)=(cx)-1

step 2:判断cx中的值,不为零则转至标号处执行,如果为零,则执行loop指令后面的内容
LOOPZ
在step2时跳转条件位CX!=0并且ZF=0
LOOPNZ
在step2时跳转条件为CX!=0并且ZF=1

LOOP和REP循环的细节

LOOP是先cx减一然后再判断cx是否为0,而REP是先判断cx是否为0,然后再减一。
也就是loop做的是do while,而rep做的是while-do

子程序

子程序分为:
(1)段内直接调用/段内间接调用
段内直接近调用CALL DST
执行的步骤为:

(1)先把CALL调用指令(不是子程序)的下一条指令的地址存入堆栈中(是为了返回主程序继续顺序执行)
(2)转移到子程序的入口地址,执行子程序的命令
实际的指令为
PUSH IP(而IP的内容存的都是下一条指令的地址,不是当前执行指令的地址)
(IP)+D16–>(IP):事实上(指令中DST给出的转向地址即子程序的入口地址),D16是转向地址与当前地址的差值(即位移量)

段内间接近调用CALL DST
指令中的DST可使用寄存器寻址方式或任一种存储器寻址方式,由指定的寄存器寻址方式或存储器的内容给出转向地址
执行的逻辑与段内直接近调用一样
具体的指令为:

PUSH IP
有效地址–>(IP)

事实上段内两种调用方式均为近调用,因此转向地址中只包含其偏移地址的部分,段地址是保持不变的
(2)段间直接远调用/段间间接远调用
段间直接远调用
直接给指令了:

PUSH CS
PUSH IP
DST指定的偏移地址–>(IP)
DST的段地址–>(CS)

值得注意的是:段地址放在高地址位,因此先入栈
段间间接远调用

PUSH CS
PUSH IP
(EA)–>(IP)
(EA+2)–>(CS)

其中EA是由DST的寻址方式确定的有效地址,这里可以用任一种存储器寻址方式来取得EA值。

习题

	MOV AL,'&'
	MOV CX,18
	CLD
	;注意SCAS是目的变址寄存器
	MOV DI,SEG STRING;返回变量或者标号的段地址值
	MOV ES,DI;赋给ES附加段寄存器
	LEA DI,STRING;获得偏移地址
	REPNZ SCASB
	JNZ EXIT
	DEC DI,1
	MOV ES:BYTE PTR [DI],' '
EXIT:
	INT 20H

公共的程序段如下:
	MOV DI,SEG PAINT_LINE
	MOV ES,DI
(1)
	MOV CX,132
	MOV AL,' '
	CLD
	LEA DI,PARINT_LINE
	REP STOSB
 (2)
 	MOV CX,9
 	MOV AL,'-'
 	CLD
 	LEA DI,STUDENT_ADDR
 	REPNZ SCASB;注意SCASB和CMPS都是使用REPZ/REPNZ
 	JNZ NO_FOUND;没找到,跳转即可
 	DEC DI;SCASB会自动增加,这里是BYTE,因此减1
 (3)
 	MOV CX,9
 	MOV AL,'-'
 	STD 
 	LEA DI,STUDENT_ADDR
 	ADD DI,9-1
 	REPNZ SCASB
 	JNZ NO_FOUND
 	INC DI
 (4)
 	MOV CX,30
 	MOV AL,' '
 	CLD
 	LEA DI,STUDENT_NAME
 	REPZ SCASB
 	JNZ NOT
 	MOV AL,'*'
 	MOV CX,30
 	CLD 
 	LEA DI,STUDENT_NAME
 	REP STOSB
 (5)
 	
 	MOV SI,SEG STUDENT_NAME
 	MOV DS,SI
 	LEA SI,STUDENT_NAME
 	MOV CX,30
 	LEA DI,PRINT_LINE
 	CLD
 	REP MOVSB
	MOV CX,9
 	STD
 	MOV SI,STUDENT_ADDR
 	ADD SI,9-1
 	MOV DI,PRINT_LINE
 	ADD DI,132-1
 	REP MOVS


注意这类题需要写成二进制,不然容易犯错
(1)
1478H=0001 …(正) BX=1000 …(你可能感觉这个80DCH是正数,实际上是负数,第一位大于等于8就为负数了)
(AX)+(BX)=负 (正加负=负)因此没有带符号的溢出
L1
(2)
B568H(负) 42C8H(正)
(AX)+(BX)= 正(负加正=正:带符号没有溢出)
L1
(3)
42C8H=正 608DH(正)
(AX)+(BX)=负(带符号的溢出),然而若是无符号数则没有溢出
L2
(4)
D023H=负 9FD0H(负)
(AX)+(BX)=6FF3H(带符号溢出,同时无符号溢出)
同时(AX)=6FF3H(正) (BX)=9FD0H(负)
(AX)-(BX)=D…(负)(带符号溢出,同时无符号溢出(有借位了))
L5
(5)
负+负=正(带符号溢出,无符号溢出)
此时(AX)=4A14H
正-负=负(带符号/无符号同时溢出)
L5

这题还有一个很坑的是,JNO没有溢出才跳转,多注意!!我看到就像转no

这种题只需要记住关键的转移指令就行,B和A是一对(分别是Below和Above代表着无符号数),而G和L是一对(分别代表着Greater和less 代表着带符号数)。E则是Equal等于的意思
可以参考里面的移位指令
无符号数:JB(小于) JNB(大于等于)JBE(小于等于)JNBE(大于)
带符号数:JL(小于)JNL(大于等于)JLE(小于等于)JNLE(大于)
这里还得提一句,如果你直接看带符号数的话,记住只要第一位大于8(1000),那么就是负数了
(1)这明显是等于,因此带等于都行
JNB JBE JNL JLE
(2)还是等于
JNB JBE JNL JLE
(3)这里带符号数 是一正一负,因此很好判断带符号数的大小,我的建议是,如果是两个负数,那么还是转成原码比较。
无符号数是大于(大于等于都是行的),带符号数是小于
JNB JNBE JL JLE
(4)同样这里是一正一负
无符号数大于,带符号数大于
JNB JNBE JNL JNLE
(5)FFC5H转成原码(正数原码补码相同的)为1000 0000 0011 1011 FF8BH转成原码为:1000 0000 01111 0101 FFC5H更大(绝对值更小)
无符号数大于,带符号数大于
JNB JBE JNL JNLE
(6)带符号数一个正数一个负数
无符号小于,带符号大于
JB JBE JNL JNLE
(7)无符号小于,带符号数小于
JB JBE JL JLE
(8)一负一正
JNB JNBE JL JLE


比较简单,不赘述了

这题需要理清思路

	MOV AL,STATUS
	AND AL,00010101B
	JZ ROUTINE_4
	JPE ROUTINE_2
	SUB AL,00010101B
	JZ ROUTINE_1
ROUTINE_3:
	JMP EXIT
ROUTINE_2:
	JMP EXIT
ROUTINE_1:
	JMP EXIT
ROUTINE_4:
	JMP EXIT
EXIT:
	INT 20H	



(1)(AX)=5H (BX)=10H(CX)=0 (DX)=0
(2)(AX)=2H(BX)=4H(CX)=3H(DX)=1H
(3)(AX)=3H(BX)=7H(CX)=2H(DX)=0

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章