汇编实验四

四、实验结论

1. 实验任务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

(2)回答问题:

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

 

 答:不能,因为add指令影响进位标志位,若add si, 2或add di, 2 产生了进位,将改变128位加法原有的进位标志位,128加法结果将会错误

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

加之前数据段(源数据):

 加之后数据段:加运算后的结果,保存在第一个数的存储空间中,即:ds:si开始的连续8个字节空间

 

2. 实验任务2

(1) 程序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

(2)运行测试截图

 

(3)回答问题:运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结 果。结合运行结果,理解代码并回答问题:

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

接收输入的字符,送到ds中偏移地址从0开始的空间中,直到输入#跳转到 next

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

(如果输入是#)2号子功能:输出换行符

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

调用2号子功能,将ds段中偏移地址从0开始的长为si的输出

 

3. 实验任务3

(1) task3.asm代码:

 1 assume cs:code, ds:data, ss:stack
 2 
 3 data segment
 4 x dw 91, 792, 8536, 65521, 2021    ;没有超出65535,所以被除数高位dx为0
 5 len equ $ - x
 6 data ends
 7 
 8 stack segment
 9     db 16 dup(0)
10 stack ends
11 
12  code segment
13 start:
14     mov ax, stack
15     mov ss, ax
16     mov sp, 16
17     mov ax, data
18     mov ds, ax
19     mov cx, len/2
20     mov si, 0
21 s:
22     mov ax, [si]             ; 低16位
23     mov dx, 0                ;高16位
24     mov di, 0               ;计数
25     call  printNumber
26     call printSpace
27     inc si      ;     下一个数
28     inc si
29     loop s
30 
31     mov ah, 4ch
32     int 21h
33 
34 printNumber:
35    s1:
36     mov dx, 0      ;高16位始终置为0
37     mov bx, 10      ;除数(16位)
38     div bx              ;(ax存商,dx存余数)
39 
40     cmp ax, 0        ;将商和0比较
41     je s2              ;商等于0转s2
42 
43     add dl, 30h      ;商不等于0转s1继续除
44     push dx           ;入栈保存余数
45     inc di              ;计数
46     jmp s1
47 
48  s2: 
49     mov bx, cx      ;保存cx                        
50     add dl, 30h     ;余数入栈,  将数字转变为数字字符,因为‘0’的ASCII码为30H
51     push dx
52     inc di            ;计数
53     mov cx, di       ;栈中有多少个余数说明得循环几次
54 printys:
55     mov ah, 2   ;打印余数
56     pop dx            ;将栈段中保存余数拿出来
57      int 21h
58      loop printys
59 
60      mov cx, bx      ;返回cx原来的值
61      ret
62 
63 printSpace:
64     mov ah, 2       ;二号子功能
65     mov dl, ' '
66     int 21h
67     ret
68 
69 code ends
70 end start

(2)运行测试截图:

 

 

 4. 实验任务4

(1) task4.asm代码

 1 assume cs:code, ds:data
 2 
 3 data segment
 4 str db "assembly language, it's not difficult but tedious"
 5 len equ $ - str
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12     mov cx, len
13     mov si, 0
14 s1:
15     call letter
16     inc si
17     loop s1
18     
19     mov ax, 4c00h
20     int 21h
21 
22 letter:
23     cmp byte ptr [si], 'a'         ;比a小不行
24     jb s2
25     cmp byte ptr [si], 'z'          ;比z大也不行
26     ja s2
27     sub byte ptr [si], 32
28 s2:
29     ret
30 
31 code ends
32 end start

(2)在debug中调试截图

call letter调用之前数据段的值:

 call letter调用之后数据段的值:(变为大写)

5. 实验任务5

(1)task5.asm源码

 1 assume cs:code, ds:data
 2 data segment
 3 str1 db "yes", '$'
 4 str2 db "no", '$'
 5 data ends
 6 code segment
 7 start:
 8 mov ax, data
 9 mov ds, ax
10 mov ah, 1
11 int 21h          ; 从键盘输入字符
12 mov ah, 2
13 mov bh, 0
14 mov dh, 24          ; 设置光标位置在第24行
15 mov dl, 70           ; 设置光标位置在第70列
16 int 10h                   ; 设置光标位置
17 cmp al, '7'
18 je s1
19 mov ah, 9
20 mov dx, offset str2
21 int 21h                   ; 显示标号str2处的字符串
22 jmp over
23 s1: mov ah, 9
24 mov dx, offset str1
25 int 21h                   ; 显示标号str2处的字符串
26 over:
27 mov ah, 4ch
28 int 21h
29 code ends
30 end start

(2)程序运行测试截图(输入7,以及输入其他字符,运行结果截图) 程序的功能是?

输入7:

输入其他字符:

功能:输入7则在指定位置打印yes,输入其他字符则在该位置打印no

 

6. 实验任务6

task6_1.asm:

 1 assume cs:code
 2 code segment
 3 
 4 task6_2.asm
 5 start:
 6 ; 42 interrupt routine install code
 7 mov ax, cs
 8 mov ds, ax
 9 mov si, offset int42 ; set ds:si
10 mov ax, 0
11 mov es, ax
12 mov di, 200h ; set es:di
13 mov cx, offset int42_end - offset int42
14 cld
15 rep movsb
16 ; set IVT(Interrupt Vector Table)
17 mov ax, 0
18 mov es, ax
19 mov word ptr es:[42*4], 200h
20 mov word ptr es:[42*4+2], 0
21 mov ah, 4ch
22 int 21h
23 int42:
24 jmp short int42_start
25 str db "welcome to 2049!"
26 len equ $ - str
27 ; display string "welcome to 2049!"
28 int42_start:
29 mov ax, cs
30 mov ds, ax
31 mov si, 202h
32 mov ax, 0b800h
33 mov es, ax
34 mov di, 24*160 + 32*2
35 mov cx, len
36 s: mov al, [si]
37 mov es:[di], al
38 mov byte ptr es:[di+1], 2
39 inc si
40 add di, 2
41 loop s
42 iret
43 int42_end:
44 nop
45 code ends
46 end start

task6_2.asm:

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     int 42             ; 调用自己实现的42号软中断
 6 
 7     mov ah, 4ch
 8     int 21h
 9 code ends
10 end start

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

运行结果:

 实现在屏幕最下方中间以黑底绿字打印"welcome to 2049!"。

 

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

   cpu收到中断信息后,转去执行该中断信息的处理程序。中断类型码用来定位中断处理程序,而中断类型码通过中断向量表找到相应的中断处理程序的入口地址(中断向量就是中断处理程序的入口地址)对于8086PC机,中断向量表指定存放在内存地址0处,0000:0000-0000:03FF的1024个单元中存放着中断向量表,且不能放在别处。

(2)自己选一个未被使用的中断码,实现一个中断例程,并调用测试。给出源码和运行测试截图。如选做,请说明你使用的中断码,并描述你实现的这个中断例程的功能。

 

实验总结

movsb可以理解为 move string byte,即字节传送指令,movsw的意思是mov string word ,字传送指令。执行完movsw或者rep movsw指令,si和di的值会增加2,或者减少2,这取决于DF标志位的值是1还是0。

 

posted @ 2021-12-10 11:33  tatazy  阅读(124)  评论(2)    收藏  举报