王爽 《汇编语言》 读书笔记 九 转移指令的原理

第九章  转移指令的原理


可以修改,或同时修改CS和IP的指令统称为转移指令。

只修改IP   jmp ax

同时修改CS和IP   jmp  1000:0


无条件转移指令jmp

条件转移指令

循环指令

过程

中断


9.1 操作符 offset

由编译器处理的符号 取得标号的偏移地址

start : mov ax, offset start

s: mov ax, offset s

将S处的代码复制到S0处

assume cs:code
code segment
s:	mov ax, bx
	mov si, offset s
	mov di, offset s0
	mov ax, cs:[si]
	mov cs:[di], ax
s0:	nop
	nop
code ends
end

运行结果


9.2 jmp指令

jmp给出两种信息

1)转移的目标地址

2)转移的距离(段间转移,段内转移,段内近转移)


9.3 依据位移进行转移段jmp指令

jmp short 标号   段内短转移对IP对修改范围在 -128~127

例子

assume cs:code
code segment
start:	mov ax, 0
		jmp short s
		add ax, 1
	s:	inc ax
code ends
end start

编译后在debug中对机器码


jmp short s0 被编译成  EB03  并不包含目标地址

CPU在执行jmp指令的时候并不需要转移的目的地址

EB03 表示在当前IP基础上向后位移3个字节的地址 也就是  jmp short  s  编译以后包含的数据是位移量

jmp short 标号    (IP) = (IP) + 8位位移量

1)8位位移=标号处的地址-jmp指令后的第一个字节的地址

2)short指明此处的位移为8位位移

3)8位位移的范围是-128~127,用补码表示

4)8位位移由编译程序在编译时算出

还有一种

jmp near ptr 标号   (IP)= (IP)+16位位移

1)16位位移=标号处的地址-jmp指令后的第一个字节的地址

2)near ptr指明此处的位移为16位位移,进行段内近转移

3)16位位移的范围是-32768~32767,用补码表示

4)16位位移由编译程序在编译时算出


9.4 转移的目的地址在指令中的jmp指令

assume cs:code
code segment
start:	mov ax, 0
		mov bx, 0
		jmp far ptr s
		db 256 dup (0)
	s:	add ax, 1
		inc ax
code ends
end start


9.5 转移地址在寄存器中的jmp指令

jmp 16位reg

功能 (IP) = (16位reg)


9.6 转移地址中内存中的jmp指令

1)jmp word ptr 内存单元地址(段内转移)

jmp word ptr ds:[0]


jmp word ptr [bx]

2)jmp dword ptr 内存单元地址(段间转移)

二个字单元,高地址字单元存放段地址,低地址字单元存放偏移地址


(CS) = (内存单元地址+2)

(IP) = (内存单元地址)


9.7 jcxz 指令

条件转移指令,所有段条件转移指令都是短转移,对应的机器码中包含转移的位移而不是目的地址。

指令格式

jcxz  标号 (如果(cx)= 0, 转移到标号处执行)

操作  当 (cx)= 0,  (IP) = (IP)+ 8位位移

8位位移 = 标号处地址 - JCXZ指令后的第一个字节的地址

8位位移量范围-128~127,用补码表示

8位位移由编译器中编译时算出


当(CX)!=0 时 程序什么也不做

监测点9.2 查找从内存2000H段中第一个值位0段字节,找到后将他的偏移地址存储在dx中

;find the first address from segment 2000H 
;with the value of the address equal to zero
assume cs:code
code segment
start:	mov ax, 2000h
		mov ds, ax
		mov bx, 0
		
	s:	mov cl, ds:[bx]
		mov ch, 0
		jcxz ok
		inc bx
		jmp short s
	
	ok:	mov dx, bx
		mov ax, 4c00h
		int 21h
code ends
end start


9.8 loop 指令

所有循环指令都是短转移,中对应机器码中包含转移的位移,而不是目的地址。

(cx)= (cx) - 1

如果  (cx) != 0 跳转至标号处  (IP)= (IP)+8位位移

8位位移 = 标号处地址 - loop指令后的第一个字节的地址

8位位移量范围-128~127,用补码表示

8位位移由编译器中编译时算出


loop的功能等于 if(cx != 0) jmp short 标号;


检测点9.3

使用loop 在内存2000H处查找第一个值位0的字节

;find the first address from segment 2000H 
;with the value of the address equal to zero
assume cs:code
code segment
start:	mov ax, 2000h
		mov ds, ax
		mov bx, 0
		
	s:	mov cl, ds:[bx]
		mov ch, 0
		inc cx
		inc bx
		loop s
	
	ok:	dec bx
		mov dx, bx
		mov ax, 4c00h
		int 21h
code ends
end start

 9.9 根据位移进行转移的意义

jmp short 标号

jmp near ptr 标号

jcxz 标号

loop 标号

为了方便程序段在内存中的浮动装配


9.10 编译器对转移位移超界对检测

以下代码编译会报错

assume cs:code
code segment
start:	jmp short s
		db 255 dup (0)
	s: 	mov ax, 0ffffh
code ends
end start

实验8

分析以下程序是否可以运行

assume cs:codesg
codesg segment
		mov ax, 4c00h
		int 21h
start:	mov ax, 0
	s:	nop
		nop
		
		mov di, offset s
		mov si, offset s2
		mov ax, cs:[si]
		mov cs:[di], ax
		
	s0:	jmp short s
	
	s1:	mov ax, 0
		int 21h
		mov ax, 0
		
	s2: jmp short s1
		nop
codesg ends
end start



可以看到,程序可以正常返回。利用来位移jmp最终程序跳转到开头的mov ax,4c00h  和  int 21h


实验9 根据实验材料编程在屏幕中央输出彩色字符


assume cs:code, ds:data, ss:stack
;the data segment store the string and the color info
data segment
		;00h
		db 'welcome to masm!'	;16 character
		
		;10h
		db	2h	; bkColor = black, color = green (0 000 0 010B)
		db	24h ; bkColor = green, color = red   (0 010 0 100B)
		db	71h	; bkColor = white, color = blue  (0 111 0 001B)
		
		;13h
		dw	5a0h ; map to the start 11th line position of the VRAM  5a0h + 40h
		;15h
		dw	40h	 ; the offset position to write the first character of the line
data ends

stack segment
		db 16 dup (0)
stack ends

code segment
start:	mov ax, data			; map ds to data segment
		mov ds, ax
		
		mov ax, 0b800h			; map es to vga ram segment
		mov es, ax
		
		mov ax, stack			; map ss to stack segment
		mov ss, ax
		mov sp, 10h				
		
								; init reg
		mov cx, 3				; write for three line
		mov bx, 0				; for line number

		mov bp, ds:[13h]		; load the address fot vram
		add bp, ds:[15h]		; add the offset address
		
	s:	push cx
		mov cx, 16				; write for 16 characters
		mov si, 0				; pointer to character array
		mov di, 0				; pointer to the target vram

	s0:	mov al, ds: 00h[si]		; read char to ax
		mov ah, ds: 10h[bx]		; read color info
		mov es:[bp][di], ax		; store the char and color info to vram
		
		inc si
		add di, 2
		loop s0
		
		
		add bp, 0a0h			; point to the next line
		inc bx
		pop cx
		loop s

		mov ax, 4c00h
		int 21h
code ends

end start





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值