实验13 编写、应用中断例程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhaixh_89/article/details/101517251

(2)编写并安装int 7ch中断例程,功能为完成loop指令的功能。

参数:(cx)=循环次数,(bx)=位移。

       以上中断例程安装好后,对下面的程序进行单步跟踪,尤其注意int,iret指令执行前后cs,ip的和栈中的状态。



    assume cs:code

    code segment

    start:  mov ax, 0b800H

            mov es, ax

            mov di, 160*12

           

            mov bx, offset s – offset se

            mov cx, 80

        s:  mov byte ptr es:[di], '!'

            add di, 2

            int 7cH

        se: nop

     

            mov ax, 4c00H

            int 21H

    code ends

    end start

程序分析:

为了模拟loop指令, 7ch中断例程必须具备下面功能

1、dec 程序

2、如果cx≠0,转到标号s处执行,否则继续向下执行

转移到标号s处需要设置CS = 标号s的段地址,IP = 标号s的偏移地址,我们知道,在7ch中断触发后,当前的标志寄存器、CS和IP都要压栈,此时压入的CS和IP中的内容分别是调用程序的段地址(可以认为是标号s的段地址)和7ch后一条指令的偏移地址(即标号se的偏移地址)

   可见,在中断例程中,可以从栈里取得标号s的段地址和标号se的偏移地址, 而用标号se的偏移地址加上bx中存放的转移位移就可以得到标号s的偏移地址,至此,我们已经可以写出中断例程如下:

showstr:push bp
        mov bp, sp
	dec cx
	jcxz ok
	add [bp + 2], bx
     ok:pop bp
	iret
  showend:nop

因为要访问栈,程序中使用了bp,开程序开始处将bp入栈保存, 结束时出栈恢复,当要修改栈中se的偏移地址的时候,栈中的情况如下图:

扫描二维码关注公众号,回复: 7599721 查看本文章

此时,栈顶为bp,所以se的偏移地址为ss*16+bp+2,将它加上bx中的转移位移就标为s的偏移地址,最后用iret出栈返回,CS:IP即从标号s处开始执行指令,如果cx=0,则不需要修改栈中se的偏移地址,直接返回即可。CPU从se处向下执行指令

完成源码如下:

assume cs:code
code segment
      start:mov ax, cs
	    mov ds, ax
	    mov si, offset showstr
		  
	    mov ax, 0
	    mov es, ax
	    mov di, 200h
	    mov cx, offset showend - offset showstr
		  
	    cld
	    rep movsb
		  
            mov ax, 0
	    mov es, ax
            mov word ptr es:[7ch*4], 200h
	    mov word ptr es:[7ch*4 + 2], 0
	
            mov ax, 0b800h
	    mov es, ax
	    mov di, 160*12
	    mov bx, offset s - offset se
		  
	    mov cx, 80
          s:mov byte ptr es:[di], '!'
	    add di, 2
	    int 7ch
	 se:nop
		  
  showstr:push bp
	  mov bp, sp
	  dec cx
	  jcxz ok
	  add [bp + 2], bx
       ok:pop bp
	  iret
  showend:nop
	  mov ax, 4c00h
	  int 21h
code ends
end start

执行结果:

(3)下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全程序。

程序源码为:

assume cs:code
code segment
	s1:	db 'Good, better, best,','$'
	s2:	db 'Never let it rest,', '$'
	s3:	db 'Till good is better,', '$'
	s4:	db 'And better, best.', '$'
	s:	dw offset s1, offset s2, offset s3, offset s4
	row: db 2, 4, 6, 8
	start:mov ax, cs
		  mov ds, ax
		  mov bx, offset s
		  mov si, offset row	;行数索引
		  mov cx, 4				;共需要4行数据
	   ok:mov bh, 0				;第0页
		  mov dh, [si]			;第几行
		  mov dl, 0				;第几列
		  mov ah, 2				;置光标功能
		  int 10h				;调用10h号中断处理程序的2号子程序
		  
		  mov dx, [bx]			;在光标处显示字符串
		  mov ah, 9				;调用21h号中断处理程序的9号子程序
		  int 21h
		  
		  inc si				
		  add bx, 2				;dw定义字型数据,增量为2
		  loop ok
		  mov ax, 4c00h
		  int 21h
code ends
end start

程序执行结果:

题目灵活利用标号偏移地址指出各数据段的内存地址,其次,每次字符串都以$结尾,可利用21h中断的9号处理程序来完成题目要求

猜你喜欢

转载自blog.csdn.net/zhaixh_89/article/details/101517251