实验4 8086标志寄存器及中断

一、实验目的

1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。
2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现
分支和循环的用法
3. 了解软中断指令的用法,体验和理解中断原理
4. 综合应用寻址方式和汇编指令完成简单应用编程
二、实验准备
复习教材「第10章 call和ret指令」、「第11章 标志寄存器」
学习教材「第12章 内中断 」、「第13章 int指令」
三、实验内容
1. 实验任务1
验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。
在debug环境中,分别实践、观察:
① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?
② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

  

使用任意文本编辑器,录入8086汇编源码task1.asm。
task1.asm

assume cs:code, ds:data
data segment
 x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
data ends
code segment
start:
  mov ax, data
  mov ds, ax
  mov si, offset x
  mov di, offset y
  call add128
  mov ah, 4ch
  int 21h
add128:
  push ax
 push cx
  push si
  push di
  sub ax, ax
  mov cx, 8
s: mov ax, [si]
  adc ax, [di]
  mov [si], ax
  inc si
  inc si
  inc di
  inc di
  loop s
  pop di
  pop si
  pop cx
  pop ax
  ret
code ends
end start

其中:
add128是子程序子程序。

功能:实现计算两位128位数的加法
入口参数:
ds:si指向存储第一个128位数的存储空间(因为一个数128位,需要8个字节的连续空间)
ds:di指向存储第二个128位数的存储空间
出口参数:
加运算后的结果,保存在第一个数的存储空间中,即:ds:si开始的连续8个字节空间

在代码段中,调用add128实现对标号x和y处存储的两个128位数据相加,结果保存在x处的连续128个字
节中。
对程序进行汇编、链接,得到可执行程序task1.exe。在debug中调试程序,并回答问题。
① line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

add si, 2
add di, 2

 

此题能进行替换,因为在此题中两个128位数进行相加时并未产生进位,也没有出现运算结果为0的情况。将原代码进行替换后并不影响计算结果和标志寄存器中标志位ZF、CF的值。

但是在其他情况中(结果产生进位,或运算结果为0时)不能替换,否则将影响最终运算结果

 

② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。

执行inc指令:

 执行add指令:

  

由图可知,数据段中做128位加之前,存放的是两个128位数。进行加之后,原来存放第一个128位数的空间用来存放原来两个128位数之和。

 

2. 实验任务2
使用任意文本编辑器,录入8086汇编源码task2.asm。
task2.asm

assume cs:code, ds:data
data segment
    str db 80 dup(?)
data ends
code segment
start: 
    mov ax, data
    mov ds, ax
    mov si, 0
s1:    
    mov ah, 1
    int 21h
    mov [si], al
    cmp al, '#'
    je next
    inc si
    jmp s1
next:
    mov ah, 2
    mov dl, 0ah
    int 21h
   
    mov cx, si
    mov si, 0
s2:   mov ah, 2
    mov dl, [si]
    int 21h
    inc si
    loop s2
    mov ah, 4ch
    int 21h
code ends
end start

对源程序task2.asm进行汇编、链接,得到可执行文件task2.exe。
运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运
行结果,理解代码并回答问题:

① 汇编指令代码line11-18,实现的功能是?

调用int 21h的1号子功能,将从键盘输入的字符串中各字符依次存放到data数据段中,直至输入的字符为'#',通过je指令跳转到next标号,结束对字符的读入。

② 汇编指令代码line20-22,实现的功能是?

调用int 21h的2号子功能,输出换行符到屏幕上。

③ 汇编指令代码line24-30,实现的功能是?

调用int 21h的2号子功能,循环依次打印之前输入的字符


说明:task2.asm中用到的两个DOS系统功能调用:

DOS系统功能调用int 21h的1号子功能

功能:从键盘上输入单个字符

入口参数:(ah) = 1
出口参数: (al)存放输入字符的ASCⅡ码

即:

mov ah, 1
int 21h ; (al) <-- 输入字符的ascⅡ码

DOS系统功能调用int 21h的2号子功能
功能:输出单个字符到屏幕上
入口参数:(ah) = 2, (dl) = 待输出的字符或其ascⅡ码
出口参数:无
即:

 

mov ah, 2
mov dl, ×× ; ××是待输出的字符,或,其ascⅡ码
int 21h

3. 实验任务3
针对8086CPU,已知逻辑段定义如下:

data segment
  x dw 91, 792, 8536, 65521, 2021
  len equ $ - x
data ends

编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据
之间以空格间隔。
要求:

  • 编写子程序printNumber

      功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)
      入口参数:寄存器ax(待输出的数据 --> ax)
      出口参数:无

  • 编写子程序printSpace

      功能:打印一个空格
      入口参数:无
      出口参数:无

  • 在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。

正确编写后,预期测试结果如下:

提示:
题目限定了数据范围是0 ~ 65535, 可以借助32÷16位的除法,无需考虑除法溢出问题。具体地:
1. 被除数 -> dx:ax,由于数据不超过65535,所以,每次寻址取数-> ax后,在子程序printNumber中做
除法时,dx设置为0即可。
2. 除以10,得到余数后,入栈并计数。重复这一过程,直至商为0。然后,循环出栈,并借助int 21h中
的2号子功能,实现输出。
3. 注意事项:① 数字和数字字符的区别,及,必要转换;② 寄存器使用冲突问题,可借助栈解决。具体
地,如内容不熟悉,请复习第10章。

代码如下:

assume ds:data, cs:code, ss:stack
data segment
  x dw 91, 792, 8536, 65521, 2021
  len equ $ - x
data ends
stack segment
  dw 8 dup(0)
stack ends

code segment
  start:
    mov ax, data
    mov ds, ax
    mov ax, stack
    mov ss, ax
    mov sp, 16
    mov si,  offset x
    mov cx, len/2 ;
    s:
      mov ax, [si]
      mov dx, 0
      call printNumber
      call printSpace
      inc si
      inc si
      loop s
    mov ah, 4ch
    int 21h

  printNumber:
    push cx
    mov cx, 0
    s1:
      mov dx, 0
      mov bx, 10
      div bx
      push dx
      inc cx
      cmp ax, 0
      jne s1
    s2:
      pop dx
      or dl, 30h
      mov ah, 2
      int 21h
      loop s2
  pop cx
  ret

  printSpace:
    mov dl, ' '
    mov ah, 2
    int 21h
  ret

code ends
end start

  运行结果:

 

4. 实验任务4
针对8086CPU,已知逻辑段定义如下:

data segment
  str db "assembly language, it's not difficult but tedious"
  len equ $ - str
data ends

编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。
要求:

  • 编写子程序strupr

      功能:将包含任意字符的字符串中的小写字母变成大写
      入口参数
          (ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si
          (cx) 字符串的长度
      出口参数:无

  • 在主体代码中,设置入口参数,调用strupr, 实现题目要求。

代码如下:

assume cs:code, ss:stack, ds:data
data segment
    str db "assembly language, it's not difficult but tedious"
    len equ $ - str
data ends

stack segment
    db 8 dup(0)
stack ends

code segment
start:
  mov ax, data
  mov ds, ax
  mov ax, stack
  mov ss, ax
  mov sp, 8
  mov si, 0
  mov cx, len
  call strupr
  call printStr

  mov ax, 4c00h
  int 21h
strupr:
  push cx
  push si
  trans:
    mov al, ds:[si];
    cmp al, 'a'
    jl next
    cmp al, 'z'
    jg next
    and al, 0dfh
    mov ds:[si], al
    next:
      inc si
      loop trans
  pop si
  pop cx
  ret
printStr:
  push cx
  push si
  print:
    mov ah, 2
    mov dl, ds:[si]
    int 21h
    inc si
  loop print
  pop si
  pop cx
  ret
code ends
end start

  在debug中调试截图( call strupr 调用之前,数据段的值,以及,调用之后,数据段的值)

 

 

5. 实验任务5
使用任意文本编辑器,录入8086汇编源码task5.asm。
task5.asm

assume cs:code, ds:data
data segment
  str1 db "yes", '$'
  str2 db "no", '$'
data ends
code segment
start:
  mov ax, data
  mov ds, ax
  mov ah, 1
  int 21h ; 从键盘输入字符
  mov ah, 2
  mov bh, 0
  mov dh, 24 ; 设置光标位置在第24行
  mov dl, 70 ; 设置光标位置在第70列
  int 10h ; 设置光标位置
  cmp al, '7'
  je s1
  mov ah, 9
  mov dx, offset str2
  int 21h ; 显示标号str2处的字符串
  jmp over
s1: mov ah, 9
  mov dx, offset str1
  int 21h ; 显示标号str2处的字符串
over: 
  mov ah, 4ch
  int 21h
code ends
end start

对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。
运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。
说明:task5.asm中,使用用到的DOS系统功能调用和BIOS中断例程

DOS系统功能调用int 21h的1号子功能
功能:从键盘上输入单个字符
入口参数:(ah) = 1

出口参数: (al)存放输入字符的ASCⅡ码
即:

 

mov ah, 1
int 21h ; (al) <-- 输入字符的ascⅡ码

DOS系统功能调用int 21h的9号子功能
功能:显示字符串
入口参数:(ah) = 9,(ds:dx) = 字符串的首地址的段地址和偏移地址
出口参数: 无
其它要求:字符串必须以$结束
即:

 

mov ah, 9
mov ds, ×× ; ××是待输出字符串所在段的段地址
mov dx, ×× ; ××是待输出字符串第一个字符的偏移地址
int 21h

 

BIOS中断例程int 10h的2号子功能
功能:设置光标位置
入口参数:(ah) = 2, (bh) = 页号(默认取0), (dh) = 行号, (dl) = 列号
出口参数:无
即:

mov ah, 2
mov bh, ×× ; ××是页号
mov dh, ××
mov dl, ×× ; ××是列号
int 10h

运行结果如图:

 

 

功能:输入一个字符,如果是7的话在24行70列输出yes,否则输出no

6. 实验任务6
实验任务1、2、3、5中使用了不少系统提供的中断例程。本实验任务中,要求自行实现一个42号软中断
例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to
2049!"。
建议配合教材第12章学习理解并实践。
task6_1.asm

assume cs:code
code segment
start:
  ; 42 interrupt routine install code
  mov ax, cs
  mov ds, ax
  mov si, offset int42  ; set ds:si
  mov ax, 0
  mov es, ax
  mov di, 200h     ; set es:di
  mov cx, offset int42_end - offset int42
  cld
  rep movsb
  ; set IVT(Interrupt Vector Table)
  mov ax, 0
  mov es, ax
  mov word ptr es:[42*4], 200h
  mov word ptr es:[42*4+2], 0
  mov ah, 4ch
  int 21h
int42:
  jmp short int42_start
  str db "welcome to 2049!"
  len equ $ - str
  ; display string "welcome to 2049!"
int42_start:
  mov ax, cs
  mov ds, ax
  mov si, 202h
  mov ax, 0b800h
  mov es, ax
  mov di, 24*160 + 32*2
  mov cx, len
s: mov al, [si]
  mov es:[di], al
  mov byte ptr es:[di+1], 2
  inc si
  add di, 2
  loop s
  iret
int42_end:
 nop
code ends
end start

task6_2.asm

assume cs:code
code segment
start:
  int 42 ; 调用自己实现的42号软中断
  mov ah, 4ch
  int 21h
code ends
end start

对汇编源程序task6_1.asm进行汇编、链接,得到可执行程序task6_1.exe。运行task6_1.exe,实现将
42号中断处理程序安装到0:200开始的连续内存空间,并设置中断向量表,使得将来通过 int 42 ,系统
可以跳转到中断处理程序。
对汇编源程序task6_2.asm进行汇编、链接,得到可执行程序task6_2.exe。运行task6_2.exe。
两个程序正确编写、汇编、链接,运行后,预期结果如下:

  • 通过此项实现任务,你对中断、软中断的理解
  • 自己选一个未被使用的中断码,实现一个中断例程,并调用测试。给出源码和运行测试截图。(选做*)

    8086一共提供了256个中断,中断码为0~255,其中,有些保留作为系统用,有些未使用。可以自
    行挑选一个未被使用的中断码,程时自己编写中断例程。

28H ~ 2EH DOS保留用(实验任务6中,使用的是42号中断码,即2AH)
30H ~ 3FH DOS保留用
60H ~ 6FH 用户保留
F1 ~ FFH 未使用

运行结果如下:

 

中断:CPU在接收到外部发送的或内部产生的一种特殊信息时,会立即处理特殊信息。

软中断:CPU内部产生特殊信息(如除法错误、单步执行、执行into指令和执行int指令)时,立即处理该情况。

 

posted @ 2021-12-13 18:57  lcha  阅读(45)  评论(4编辑  收藏  举报