编写包含多个功能子程序的中断例程|直接定址表的相对偏移地址问题

直接定址表的相对偏移地址问题

在这里插入图片描述

一开始定义的偏移地址如下

table dw f1,f2,f3,f4

程序不能正常运行,debug发现,偏移地址偏移量过大造成的。

原来保存在table中诸如f1之类的偏移地址实际上是在安装程序进行编译时产生的,也就是说该偏移地址相对标号start处偏移的。而程序安装进内存0000:0200h后作为一个独立的中断例程,本应该相对标号setscreen偏移。所以,我们保存的偏移量应该是在f1的基础上减去setscreen的。

此外,程序在内存0000:0200h处安装,所以还要再加上200h的偏移量。所以table中保存的偏移地址应该改为:

table dw f1-offset setscreen+200h,f2-offset setscreen+200h,f3-offset setscreen+200h,f4-offset setscreen+200h

还要注意的是,table作为一个标号,能够表示偏移地址,但在这个案例中table的偏移地址也是相对标号start的。

其他的细节见注释。

assume cs:code

code segment
	
	start:
	;安装
	mov ax,0
	mov es,ax
	mov di,200h
	mov ax,cs
	mov ds,ax
	mov si,offset setscreen
	
	mov cx,offset int7end - offset setscreen
	cld
	rep movsb
	;设置中断向量表
	mov word ptr es:[7*4],200h
	mov word ptr es:[7*4+2],0
	
	mov ax,4c00h
	int 21h
	
	;--------------------------------
	setscreen:
	jmp short set
	
	table dw f1-offset setscreen+200h,f2-offset setscreen+200h,f3-offset setscreen+200h,f4-offset setscreen+200h ; 保存的是在编译时产生的偏移量

	set:
	push bx
	
	cmp ah,3
	ja sret
	mov bl,ah
	mov bh,0
	add bx,bx
	
	sub bx,offset setscreen; 使table相对于setscreen偏移,减去多余的偏移量。
	call word ptr table[bx+200h] ; table本身也是一个偏移地址
	
	sret:
	pop bx
	iret
	;--------------------------------
	f1:
	push bx
	push es
	push cx
	
	mov bx,0b800h
	mov es,bx
	mov bx,0
	
	mov cx,2000
	f1s:
	mov byte ptr es:[bx],' '
	add bx,2
	loop f1s
	
	pop cx
	pop es
	pop bx
	ret
	;---------------------------------
	f2:
	push bx
	push es
	push cx
	
	mov bx,0b800h
	mov es,bx
	mov bx,1
	
	mov cx,2000
	f2s:
	and byte ptr es:[bx],11111000b
	or byte ptr es:[bx],al
	add bx,2
	loop f2s
	
	pop cx
	pop es
	pop bx
	ret
	;---------------------------------
	f3:
	push bx
	push es
	push cx
	push ax
	
	mov bx,0b800h
	mov es,bx
	mov bx,1
	
	shl al,1
	shl al,1
	shl al,1
	shl al,1
	mov cx,2000
	f3s:
	and byte ptr es:[bx],10001111b
	or byte ptr es:[bx],al
	add bx,2
	loop f3s
	
	pop ax
	pop cx
	pop es
	pop bx
	ret
	;---------------------------------
	f4:
	push cx
	push bx
	push ds
	push es
	push si
	push di
	
	;将es:di指向n行,0~23
	mov bx,0b800h
	mov es,bx
	mov di,0
	;将ds:si指向n+1行,1~24
	mov ds,bx
	mov si,1*160
	;24次循环,利用rep movsb复制
	cld
	mov cx,24
	f4s:
	push cx
	mov cx,160
	rep movsb
	pop cx
	loop f4s
	;最后一行空格符填充
	mov cx,80
	f4ss:
	mov byte ptr ds:[si],' '
	add si,2
	loop f4ss
	
	pop di
	pop si
	pop es
	pop ds
	pop bx
	pop cx
	ret
	
	int7end:nop
	
code ends

end start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值