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

1. 实验任务1

task1.asm源码

 1 assume cs:code, ds:data
 2 
 3 data segment
 4    x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 5    y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
 6 data ends
 7 code segment 
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov di, offset y
13     call add128
14 
15     mov ah, 4ch
16     int 21h
17 
18 add128:
19     push ax
20     push cx
21     push si
22     push di
23 
24     sub ax, ax
25 
26     mov cx, 8
27 s:  mov ax, [si]
28     adc ax, [di]
29     mov [si], ax
30 
31     inc si
32     inc si
33     inc di
34     inc di
35     loop s
36 
37     pop di
38     pop si
39     pop cx
40     pop ax
41     ret
42 code ends
43 end start

line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

add si, 2

add di, 2

不能替换成如下代码。inc指令不影响标志位,add指令影响标志位。当数据有溢出时标志位CF会有区别。

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

加之前

 

 加之后

 

 2. 实验任务2

程序task2.asm源码

 

 1 assume cs:code, ds:data
 2 data segment
 3         str db 80 dup(?)
 4 data ends
 5 
 6 code segment
 7 start:  
 8         mov ax, data
 9         mov ds, ax
10         mov si, 0
11 s1:        
12         mov ah, 1
13         int 21h
14         mov [si], al
15         cmp al, '#'
16         je next
17         inc si
18         jmp s1
19 next:
20         mov ah, 2
21         mov dl, 0ah
22         int 21h
23         
24         mov cx, si
25         mov si, 0
26 s2:     mov ah, 2
27         mov dl, [si]
28         int 21h
29         inc si
30         loop s2
31 
32         mov ah, 4ch
33         int 21h
34 code ends
35 end start

 

测试截图:

 

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

从键盘上输入字符,输入的字符保存进data段中,判断是否输入'#',如果是则进行下一步操作不是则继续从键盘输入字符。

 

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

将一个换行符输出到屏幕上。

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

将之前从键盘上输入的内容输出到屏幕上。

3. 实验任务3

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

要求: 编写子程序printNumber

功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)

入口参数:寄存器ax(待输出的数据 --> ax)

出口参数:无

编写子程序printSpace

功能:打印一个空格

入口参数:无

出口参数:无

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

task3.asm源码

 

 1 assume cs:code, ds:data
 2 data segment
 3     x dw 91, 792, 8536, 65521, 2021
 4     len equ $ - x
 5 data ends
 6  
 7 code segment
 8 start:  
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov cx, 5
13     
14 s:    mov ax, [si]
15     push cx
16     call printNumber
17     call printSpace
18     add si, 2
19     pop cx
20     loop s
21     
22     mov ah, 4ch
23     int 21h
24     
25 printNumber:   
26     mov dx, 0 ;余数
27     mov cx, 0 ;
28 s1:    mov bx, 10 ;除数
29     div bx ;十进制除以10
30     push dx ;余数进栈
31     mov dx, 0 ;余数清零
32     inc cx ;位数加1
33     add ax, 0 ;ax存商,
34     jnz s1 ;商不为0继续除
35     
36 s2:    pop dx ;余数逆序输出
37     mov ah, 2 ;调用2号子功能
38     or dl, 30h ;转为对应ascii码
39     int 21h
40     loop s2
41     ret
42     
43 printSpace:
44     mov ah, 2
45     mov dl, ' '
46     int 21h
47     ret
48  
49 code ends
50 end start

 

运行测试截图:

 

 4. 实验任务4

task4.asm源码

 1 assume cs:codesg
 2 
 3 datasg segment
 4     str db "assembly language, it's not difficult but tedious"
 5     len equ $ - str
 6 datasg ends
 7 
 8 codesg segment
 9     begin:    mov ax,datasg
10             mov ds,ax
11             mov si,0
12             call strupr
13             
14 
15             mov si,0            ;恢复si
16             mov ax,0b800h
17             mov es,ax
18             ;mov di,13*160
19             mov di, 0
20             mov cx,len
21         s2:    mov al,ds:[si]
22             mov es:[di],al
23             inc si
24             add di,2
25             loop s2    
26 
27 
28 
29             mov ax,4c00h
30             int 21h
31             
32     strupr:
33             pushf        ; 保存标志寄存器的信息
34             push ds
35             push si
36             
37         s:    mov ch,0
38             mov cl,ds:[si]
39             jcxz ok
40             cmp byte ptr ds:[si],61h
41             jb s0                    ; below 低于则转移
42             cmp byte ptr ds:[si],7Ah
43             ja s0                    ; above 高于则转移
44             and byte ptr ds:[si],11011111b     ; 小写转大写
45         s0:    inc si
46             loop s
47         
48         ok:    
49             pop si
50             pop ds
51             popf         ; 还原标志寄存器的信息
52             
53             ret
54 codesg ends
55 end begin

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

调用之前

 

 

 调用之后

 

 

5. 实验任务5

task5.asm源码

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str1 db "yes", '$'
 5     str2 db "no", '$'
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12 
13     mov ah, 1
14     int 21h
15 
16     mov ah, 2
17     mov bh, 0
18     mov dh, 24
19     mov dl, 70
20     int 10h
21 
22     cmp al, '7'
23     je s1
24     mov ah, 9
25     mov dx, offset str2
26     int 21h
27 
28     jmp over
29 
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h
33 over:  
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

 

 

程序运行测试截图(输入7,以及输入其他字符,运行结果截图)

 

 

 

 

 

程序的功能是?

判断输入的内容是否为数字7,是7则在24行70列输出yes,不是7则在24行70列输出no

6. 实验任务6

通过此项实现任务,你对中断、软中断实现机制的理解

 

------------恢复内容开始------------

1. 实验任务1

task1.asm源码

 1 assume cs:code, ds:data
 2 
 3 data segment
 4    x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 5    y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
 6 data ends
 7 code segment 
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov di, offset y
13     call add128
14 
15     mov ah, 4ch
16     int 21h
17 
18 add128:
19     push ax
20     push cx
21     push si
22     push di
23 
24     sub ax, ax
25 
26     mov cx, 8
27 s:  mov ax, [si]
28     adc ax, [di]
29     mov [si], ax
30 
31     inc si
32     inc si
33     inc di
34     inc di
35     loop s
36 
37     pop di
38     pop si
39     pop cx
40     pop ax
41     ret
42 code ends
43 end start

line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

add si, 2

add di, 2

不能替换成如下代码。inc指令不影响标志位,add指令影响标志位。当数据有溢出时标志位CF会有区别。

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

加之前

 

 加之后

 

 2. 实验任务2

程序task2.asm源码

 

 1 assume cs:code, ds:data
 2 data segment
 3         str db 80 dup(?)
 4 data ends
 5 
 6 code segment
 7 start:  
 8         mov ax, data
 9         mov ds, ax
10         mov si, 0
11 s1:        
12         mov ah, 1
13         int 21h
14         mov [si], al
15         cmp al, '#'
16         je next
17         inc si
18         jmp s1
19 next:
20         mov ah, 2
21         mov dl, 0ah
22         int 21h
23         
24         mov cx, si
25         mov si, 0
26 s2:     mov ah, 2
27         mov dl, [si]
28         int 21h
29         inc si
30         loop s2
31 
32         mov ah, 4ch
33         int 21h
34 code ends
35 end start

 

测试截图:

 

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

从键盘上输入字符,输入的字符保存进data段中,判断是否输入'#',如果是则进行下一步操作不是则继续从键盘输入字符。

 

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

将一个换行符输出到屏幕上。

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

将之前从键盘上输入的内容输出到屏幕上。

3. 实验任务3

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

要求: 编写子程序printNumber

功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)

入口参数:寄存器ax(待输出的数据 --> ax)

出口参数:无

编写子程序printSpace

功能:打印一个空格

入口参数:无

出口参数:无

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

task3.asm源码

 

 1 assume cs:code, ds:data
 2 data segment
 3     x dw 91, 792, 8536, 65521, 2021
 4     len equ $ - x
 5 data ends
 6  
 7 code segment
 8 start:  
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov cx, 5
13     
14 s:    mov ax, [si]
15     push cx
16     call printNumber
17     call printSpace
18     add si, 2
19     pop cx
20     loop s
21     
22     mov ah, 4ch
23     int 21h
24     
25 printNumber:   
26     mov dx, 0 ;余数
27     mov cx, 0 ;
28 s1:    mov bx, 10 ;除数
29     div bx ;十进制除以10
30     push dx ;余数进栈
31     mov dx, 0 ;余数清零
32     inc cx ;位数加1
33     add ax, 0 ;ax存商,
34     jnz s1 ;商不为0继续除
35     
36 s2:    pop dx ;余数逆序输出
37     mov ah, 2 ;调用2号子功能
38     or dl, 30h ;转为对应ascii码
39     int 21h
40     loop s2
41     ret
42     
43 printSpace:
44     mov ah, 2
45     mov dl, ' '
46     int 21h
47     ret
48  
49 code ends
50 end start

 

运行测试截图:

 

 4. 实验任务4

task4.asm源码

 1 assume cs:codesg
 2 
 3 datasg segment
 4     str db "assembly language, it's not difficult but tedious"
 5     len equ $ - str
 6 datasg ends
 7 
 8 codesg segment
 9     begin:    mov ax,datasg
10             mov ds,ax
11             mov si,0
12             call strupr
13             
14 
15             mov si,0            ;恢复si
16             mov ax,0b800h
17             mov es,ax
18             ;mov di,13*160
19             mov di, 0
20             mov cx,len
21         s2:    mov al,ds:[si]
22             mov es:[di],al
23             inc si
24             add di,2
25             loop s2    
26 
27 
28 
29             mov ax,4c00h
30             int 21h
31             
32     strupr:
33             pushf        ; 保存标志寄存器的信息
34             push ds
35             push si
36             
37         s:    mov ch,0
38             mov cl,ds:[si]
39             jcxz ok
40             cmp byte ptr ds:[si],61h
41             jb s0                    ; below 低于则转移
42             cmp byte ptr ds:[si],7Ah
43             ja s0                    ; above 高于则转移
44             and byte ptr ds:[si],11011111b     ; 小写转大写
45         s0:    inc si
46             loop s
47         
48         ok:    
49             pop si
50             pop ds
51             popf         ; 还原标志寄存器的信息
52             
53             ret
54 codesg ends
55 end begin

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

调用之前

 

 

 调用之后

 

 

5. 实验任务5

task5.asm源码

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str1 db "yes", '$'
 5     str2 db "no", '$'
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12 
13     mov ah, 1
14     int 21h
15 
16     mov ah, 2
17     mov bh, 0
18     mov dh, 24
19     mov dl, 70
20     int 10h
21 
22     cmp al, '7'
23     je s1
24     mov ah, 9
25     mov dx, offset str2
26     int 21h
27 
28     jmp over
29 
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h
33 over:  
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

 

 

程序运行测试截图(输入7,以及输入其他字符,运行结果截图)

 

 

 

 

 

程序的功能是?

判断输入的内容是否为数字7,是7则在24行70列输出yes,不是7则在24行70列输出no

6. 实验任务6

要求自行实现一个42号软中断 例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to 2049!"。

task6_1.asm、task6_2.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
assume cs:code

code segment
start:
    int 42

    mov ah, 4ch
    int 21h
code ends
end start

 

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

 

通过此项实现任务,你对中断、软中断实现机制的理解

中断,是CPU在执行完当前正在执行的指令之后检测到外部发送或内部产生的一种特殊信息并立即对所接受信息进行处理而不是接着向执行完命令的下方指令继续执行。最大的特点就是在事件处理的先后顺序上有操作。产生中断,根据CS:IP指向的入口遵循中断向量表处理中断程序,处理完返回到出发位置。

 

posted on 2021-12-12 16:59  FlamingHotCheeto  阅读(62)  评论(2编辑  收藏  举报

导航