实验3

实验任务1

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x db 1, 9, 3
 5     len1 equ $ - x
 6 
 7     y dw 1, 9, 3
 8     len2 equ $ - y
 9 data ends
10 
11 code segment
12 start:
13     mov ax, data
14     mov ds, ax
15 
16     mov si, offset x
17     mov cx, len1
18     mov ah, 2
19  s1:mov dl, [si]
20     or dl, 30h
21     int 21h
22 
23     mov dl, ' '
24     int 21h
25 
26     inc si
27     loop s1
28 
29     mov ah, 2
30     mov dl, 0ah
31     int 21h
32 
33     mov si, offset y
34     mov cx, len2/2
35     mov ah, 2
36  s2:mov dx, [si]
37     or dl, 30h
38     int 21h
39 
40     mov dl, ' '
41     int 21h
42 
43     add si, 2
44     loop s2
45 
46     mov ah, 4ch
47     int 21h
48 code ends
49 end start

运行截图

 在debug中进行调试观察的反汇编截图

问题1:line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s1其后指令的偏移地址的。

答:(F2)h = 242 因为执行完LOOP 000D后 IP指针此时的值为001B 而 001B+F2=(01)0D   (01)溢出被舍弃 最终IP的值即为000D 符合LOOP指令应当跳转的地址值

问题2:line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。

答:(F0)h = 240 因为执行完LOOP 0029后  IP指针此时的值为0039 而 0039+F0=(01)29    (01)溢出被舍弃 最终IP的值即为0029 符合LOOP指令应当跳转的地址值

实验任务2

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     dw 200h, 0h, 230h, 0h
 5 data ends
 6 
 7 stack segment
 8     db 16 dup(0)
 9 stack ends
10 
11 code segment
12 start:  
13     mov ax, data
14     mov ds, ax
15 
16     mov word ptr ds:[0], offset s1
17     mov word ptr ds:[2], offset s2
18     mov ds:[4], cs
19 
20     mov ax, stack
21     mov ss, ax
22     mov sp, 16
23 
24     call word ptr ds:[0]
25 s1: pop ax
26 
27     call dword ptr ds:[2]
28 s2: pop bx
29     pop cx
30 
31     mov ah, 4ch
32     int 21h
33 code ends
34 end start

根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = s1 寄存器(bx) = s2 寄存器(cx) = cs

因为call word ptr ds:[0]是短转移 此时call指令先把当前ip值压栈(也就是s1对应的ip),然后进行跳转 call dword ptr ds:[2] 是长转移, 此时先把当前cs:ip值(也就是cs:s2)压栈,然后进行跳转

 

对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试结果与理论 分析结果是否一致,如下图:

 可见分析正确

实验任务3

代码

 1 assume cs:code, ds:data
 2 
 3 data segment
 4   x db 99, 72, 85, 63, 89, 97, 55
 5       ;0   1   2   3   4   5   6
 6   len equ $- x ;符号常量, $指下一个数据项的偏移地址,这个示例中,是7
 7 data ends
 8 
 9 code segment
10 start:
11   mov ax, data 
12   mov ds, ax
13 
14   mov si, offset x ; 取符号x对应的偏移地址0 -> si
15   mov cx, len 
16   mov bl, 10
17 s1:
18   mov ah, 0
19   mov al, [si]
20   call printNumber
21   call printSpace
22   inc si
23   loop s1
24 
25   mov ax, 4c00h
26   int 21h
27 
28 printNumber: 
29   div bl
30   mov dl, al;商在al
31   or dl, 30H;将数字转换为字符
32   mov bh, ah;余数在ah
33 
34   mov ah, 2
35   int 21h;打印十位数
36 
37   mov dl, bh
38   or dl, 30H
39   int 21h;打印个位数
40   ;mov ah, 2
41   ;mov dl, ××   xx是待输出的字符,或其ASCⅡ码值
42   ;int 21h
43   ret
44 
45 printSpace: 
46   mov ah, 2
47   mov dl, ' '
48   int 21h  ;输出空格
49   ret 
50 
51 code ends
52 end start

结果

 

 实验任务4

 1 assume cs:code, ds:data
 2 
 3 data segment
 4   str db 'try'
 5   len equ $ - str
 6 data ends
 7 
 8 code segment
 9 start:
10   mov ax, data 
11   mov ds, ax
12 
13   mov ax, 0b800h
14   mov es, ax
15 
16   ;在屏幕最上方以黑底绿字显示字符串
17   mov si, offset str ; 取符号x对应的偏移地址0 -> si
18   mov bh,  0; 指定行
19   call getHeadAdrOfRow
20   mov bl, 02h;指定颜色
21   mov cx, len 
22   call printStr
23 
24   ;在屏幕最下方以黑底红色显示字符串
25   mov si, offset str ; 取符号x对应的偏移地址0 -> si
26   mov bh, 24; 指定行 HeadAdrOfRow = 00A0H * n
27   call getHeadAdrOfRow
28   mov bl, 4;指定颜色
29   mov cx, len   
30   call printStr
31 
32   mov ax, 4c00h
33   int 21h
34 
35 printStr: 
36 s1:
37   mov ah, bl
38   mov al, [si]
39   mov es:[di], ax
40   inc si
41   add di, 2
42   loop s1
43   ret
44 
45 getHeadAdrOfRow:;返回第bh行的首地址di
46   mov ax, 0
47   mov bl, bh
48   mov bh, 0
49   mov cx, bx
50 s3:
51   add ax, 00A0H
52   loop s3
53   mov di, ax
54   ret
55 
56 code ends
57 end start

结果截图

 实验任务5

 1 assume cs:code, ds:data
 2 
 3 data segment
 4   stu_no db '201983290096'
 5   len = $ - stu_no
 6 data ends
 7 
 8 code segment
 9 start:
10   mov ax, data 
11   mov ds, ax
12 
13   mov ax, 0b800h
14   mov es, ax
15 
16   ;将背景设为蓝色
17   mov bh,  0; 指定从第几行开始设置背景色
18   call getHeadAdrOfRow
19   mov bl, 17h;指定背景颜色
20   call setBackground
21 
22   ;在屏幕最下方输出指定内容
23   mov si, offset stu_no ; 取符号x对应的偏移地址0 -> si
24   mov bh, 24; 指定行 HeadAdrOfRow = 00A0H * n
25   call getHeadAdrOfRow
26   mov bl, 17h;指定字体颜色  
27   call printStr
28 
29
30   mov bx, 0
31 
32   mov ax, 4c00h
33   int 21h
34 
35 setBackground:
36   ;mov cx, 1920 
37   mov cx, 2000 
38 s2:
39   mov al, ' '
40   mov ah, bl
41   mov es:[di], ax
42   add di, 2 
43   loop s2
44   ret
45 
46 printStr: 
47   call print
48 
49   mov cx, len 
50 s1:
51   mov ah, bl
52   mov al, [si]
53   ;or al, 30H
54   ;mov al, 49
55   mov es:[di], ax
56   inc si
57   add di, 2
58   loop s1
59 
60   call print
61   ret
62 
63 getHeadAdrOfRow:;返回第bh行的首地址di
64   mov ax, 0
65   mov bl, bh
66   mov bh, 0
67   mov cx, bx
68 s3:
69   add ax, 00A0H
70   loop s3
71   mov di, ax
72   ret
73 
74 print:;输出---
75   mov cx, 34
76 s4:
77   mov ah, bl
78   mov al, 45;'-'
79   mov es:[di], ax
80   add di, 2
81   loop s4
82   ret
83 
84 code ends
85 end start

结果截图

 这里要注意在设置背景色时如果希望前景色为透明,可以把字符设置为' '(空格),这样就不用担心填充时前景色字符覆盖背景的问题 

同时,如果设置背景时把前景色也设为蓝色,那么这里的F:\>就看不见了 但实际还是存在的 感兴趣的同学可以试试

posted @ 2021-11-23 23:58  monistery  阅读(89)  评论(3编辑  收藏  举报