汇编语言指令系统——控制转移类指令

无条件转移指令
转移指令JMP

转移指令: JMP 地址
功能:使程序无条件地转移到指令中指定的且标地址去执行(即地址指向的内容)

;具体例子
assume cs:code
code segment
	    mov ax,0
	    jmp s 			;跳过add ax,1  执行inc ax
	    add ax,1
	  s:inc ax
code ends
     end
段内转移和段间转移(近转移和远转移)

在这里插入图片描述

段内转移(近转移near)
特点:目标地址和JMP指令在同一个代码段
不需要更改CS段地址,只要改变IP偏移地址
短转移short是近转移的一个特例( 16位到8位)(为段内转移的特例)
短转移short转移范围在段内-128~+127范围的转移

1、段内直接转移指令
格式:JMP label(符号地址)

;例子
again:	dec cx	;标号again的指令
	……
	jmp again	;转移到again处继续执行
	……
	jmp output	;转向output
	……
output:	mov result,al	;标号output的指令

2、段内间接转移指令
格式:JMP r16/word ptr m16 ;IP←r16/m16
将一个16位寄存器或主存字单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容

jmp ax		;IP←AX
jmp word ptr [2000h]	;IP←[2000h]

段间转移(远转移far)
特点:目标地址和JMP指令在不同代码段
需要更改CS段地址和IP偏移地址
目标地址必须用一个32位数表达(32位远指针)

1、段间直接(远)转移指令
格式:JMP far ptr label;IP←label的偏移地址 CS←label的段地址

将标号所在段的段地址作为新的CS值,标号在该段内的偏移地址作为新的IP值;这样,程序跳转到新的代码段执行

2、段间间接转移指令
格式:JMP far ptr mem
;IP←[mem],CS←[mem+2]
用一个双字存储单元表示要跳转的目标地址。这个目标地址存放在主存中连续的两个字单元中的,低位字送IP寄存器,高位字送CS寄存器

mov word ptr [bx],0
mov word ptr [bx+2],1500h
JMP far ptr [bx]    ;转移到1500h:0
条件转移指令
JCC指令

指令格式:Jcc label;条件满足,发生转移:IP←IP+8位位移量;条件不满足,顺序执行
如果条件cc成立,程序转移到由标号label指定的目标地址去执行指令;
如果条件cc不成立,则程序将顺序执行下一条指令
条件转移指令都是段内短转移
转移范围与JMP SHORT 指令相同
-128~+127个单元的范围之内

标志位知识回顾

在这里插入图片描述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。

直接标志转移指令

基于1个状态标志位状态(同一组指令跳转条件均为前面的对应状态为1,后面那个对应状态为0)

  1. JC,JNC
    判断CF的状态,常用于两个无符号数比较大小
  2. JZ/JE,JNZ/JNE
    判断ZF的状态,常用于循环体的结束判断
  3. JS, JNS
    判断SF的状态,常用于判断数的性质
  4. JO, JNO
    判断OF的状态,常用于有符号数溢出的判断
  5. JP/JPE, JNP/JPO
    判断PF的状态,常用于判断结果低8位1的个数是否为偶数
    各种例子
;JC/JNC:记录BX中1的个数
	xor al,al	;AL=0,CF=0
again:	test bx,0ffffh ;等价于 cmp bx,0
	je next        ;bx=0跳到next
	shl bx,1
	jnc again      ;cf=0跳到again
	inc al
	jmp again
next:	...	;AL保存1的个数
;JS/JNS 指令   计算|X-Y|(绝对值)
;X和Y为存放于X单元和Y单元的16位操作数;结果存入result
	mov ax,X
	sub ax,Y
	jns nonneg   ;结果非负,为正
	neg ax	;neg是求补指令
nonneg:	mov result,ax
;JO/JNO指令:计算X-Y;
;X和Y为存放于X单元和Y单元的16位操作数;若溢出,则转移到overflow处理
	mov ax,X
	sub ax,Y
	jo overflow...	;无溢出,结果正确
overflow:	...	;有溢出处理
间接标志跳转指令(无符号数)

无符号数高低有4种关系:

  1. JA (JNBE) --CF V ZF=0(大于)
  2. JAE (JNB)-----CF=0 (大于等于)
  3. JB (JNAE) -----CF=1 (小于)
  4. JBE (JNA)-----CF V ZF=1 (小于等于)
    注()内为指令的等价指令,CF=1 小于,ZF=1 等于
    例子
    编写一程序段,实现比较两个无符号数的大小,将较大者存放在AX寄存器中
cmp ax,bx 	;比较ax和bx,(AX)-(BX)
jae next		;若ax>bx,转移
xchg ax,bx	;若ax<bx,交换
next: 
间接标志跳转指令(比较有符号数)

1)JG (JNLE) ----(SF 异或 OF) V ZF=0 (大于)
2)JGE (JNL)-----SF 异或 OF=0 (大于等于)
3)JL (JNGE)------SF 异或 OF=1 (小于)
4)JLE (JNG)-----(SF 异或 OF) V ZF=1 (小于等于)

;JG:AL, BL, CL中有3个符号数,将最大数存于AL中
          	CMP  AL, BL ;比较AL,BL的大小
         	 JG   LL           ;AL>BL时程序转到LL
      	    XCHG  AL, BL
LL: 		CMP  AL, CL      	       
  	  	 	JG  EXIT        ;AL>CL时转到EXIT
           	XCHG  	AL, CL    	;AL≤BL
EXIT: 
;JGE:计算X-Y的绝对值,X,Y为字类型有符号数,结果存入RESULT
        	MOV  	AX, X    
        	SUB   	AX, Y
        	JGE  	M          		;
        	NEG  	AX
  M :		MOV  	RESULT, AX
循环指令

循环范围:以当前IP为中心的-128~127范围内循环
循环次数:默认CX寄存器指定
无条件循环指令
LOOP label ;CX←CX- 1,
; CX≠0,循环到标号label,无条件循环指令
;相当于DEC CX
JNZ label

     mov ax,2           ;ax=2
     mov cx,3           ;cx=3
 s:add ax,ax           ;ax=2+2=4
    loop s                 
当执行到loop时①cx=cx-1, cx=2
                          ②如果cx≠0,转到s
mov cx,循环次数
s: 循环执行的程序段
       loop s

LOOPZ label ;CX←CX-1,
;CX≠0且ZF=1,循环到标号label
注,两个字符比较
LOOPNZ label ;CX←CX-1,
;CX≠0且ZF=0,循环到标号label
注:一般用于字符串中是否有某个字母

;编写一段程序,实现1+2+。。。。+100,把结果放入AX中。
	XOR AX,AX;清空AX
	MOV CX,100
	MOV BX,1
S:	ADD AX,BX
	INC BX
	LOOP S	
;方法二
	XOR AX,AX
	MOV CX,100
S:	ADD AX,CX
	LOOP S;
子程序调用及返回指令

*子程序是完成特定功能的一段程序
*当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行
*当运行完子程序功能后,采用RET返回指令回到主程序继续执行
*CALL指令和RET指令都丕影响状态标志位

在这里插入图片描述

子程序的调用

调用指令的执行过程
1.保护断点
将调用指令的下一条指令的地址(断点)压入堆栈
2.获取子程序的入口地址
子程序第一条指令的地址
3.执行子程序(程序员完成)
功能实现,参数的保存及恢复
4.恢复断点
将断点的偏移地址弹出

子程序调用指令
子程序调用指令与JMP类似

CALL指令分成4种类型

  1. CALL子程序名 ;段内直接调用
  2. CALL r16
    CALL WORD PTR m16;段内间接调用
  3. CALL far ptr子程序名 ;段间直接调用
  4. CALL DWORD ptr mem ;段间间接调用

CALL指令需要保存返回地址:
段内调用一在 同一代码段内进行,也称近调用
偏移地址IP入栈
SP←-SP- 2, SS:[SP]← IP
段间调用一在不同代码段之间进行,也称远调用
段地址CS和偏移地址IP和入栈
SP←-SP- 2, SS:[SP]← CS
SP←SP- 2,SS:[SP]← IP

子程序返回指令

功能:弹出堆栈中由CALL指令压入的返回地址值,迫使CPU返回到主程序中CALL指令的下一条指令去继续执行,该指令常放在子程序的最后
说明:根据段内和段间、有无参数,具体分成4种情况
(1) RET ;无参数返回
(2) RET n ;有参数返回
n:多弹出几个字。
需要弹出CALL指令压入堆栈的返回地址
(3)段内返回——偏移地址IP出栈
IP←-SS:[SP], SP← -SP+2
(4)段间返回——偏移地址IP和段地址CS出栈
IP←SS:[SP], SP←-SP+2
CS←SS:[SP], SP←SP+2

中断指令

中断指令
1、中断指令INT
格式: INT n
多种中断
功能:产生一个中断类型号为n的内部中断,其n值是一一个0~FFH范围内的整数
2、溢出中断指令INTO
格式: INTO
功能:产生一个溢出中断
3、中断返回指令IRET
功能:退出中断过程,返回到中断时的断点处继续执行。所有的中断程序,不管是由软件引起还是由硬件引起,其最后一条指令必须是IRET

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(1) 根据下述情况,分别编写程序,记录 BX 1 的个数(需要考虑 BX 二进制 串的特殊情况),要求如下:  循环次数已知  循环次数未知 (2) 按照下列要求,编写相应程序段。 1) 起始地址为 string 的主存单元存放一个字符串(长度大于 6),把 该字符串的第 1 个和第 6 个字符(字节量)传送给 DX 寄存器; 2) 从主存 buffer 开始的 4 字节保存了 4 个非压缩 BCD 码,现按低(高) 地址对低(高)位的原则,将他们合并到 DX 。 3) 假设从 B800H:0 开始存放有 100 个 16 位无符号数,编程求它们的和, 并存在 DX.AX 4) 一个 100 字节元素的数组首地址为 array,将每个元素减 1(不考虑 溢出)。 (3) 把内存从 PACKED 开始的 10 个字节单元的 16 位压缩 BCD 数转换成非压 缩 BCD 数,并把结果存放在 UNPACKED 开始的 20 个字节单元;将下列代 码补充完整,并且自己定义 PACKED 的数据,将 UNPACKED 的结果展示 出来。 MOV DX, _____ MOV CL, ______ MOV SI, 0 MOV DI, ___ CONVERT: MOV AL, [SI+PACKED] MOV AH, AL AND AL, 0FH __________ MOV [DI+UNPACKED], ____ 汇编语言实验(五) ADD DI, ____ ______ DEC DX JNZ CONVERT (4) 给定一个有序数组(均小于 FFH 例如 02H, 07H, 0BH, 0FH, 13H, 1CH, 24H, 39H, 40H, 57H, 68H)和一个目标值(例如 79H),请判断数组是否含有两个数的 和为目标值,请设计一个算法,将时间复杂度控制在 O(n),编程实现并验证 你的算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值