1. 实验任务1

教材「实验9 根据材料编程」(P187-189)编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。

解题思路:根据学习的知识,我知道该页在显示缓冲区的位置从B8000H开始,要在屏幕中间,对照表格,我输出的三行应是11,12,13行。11行的起始地址为1760,我的输入内容占16bytes*2=32。(160-32)/2=64。所以我的初始地址偏移量是1760+64=1824,转换为十六进制是720h。B8000H+720H=B8720H,所以我把初始es设置为B872,这样偏移变量就从0开始。

编写代码的想法,内层循环控制每行输出字符,外层循环控制打印三行。

 1 assume cs:code, ds:data, ss:stack
2 data segment
3 db 'welcome to masm!'
4 db 2h,24h,71h ;颜色
5 data ends
6 stack segment stack
7 db 16 dup (0)
8 stack ends
9
10 code segment
11 start:
12 mov ax,data
13 mov ds,ax
14 mov ax,stack
15 mov ss,ax
16 mov sp,16
17 mov ax,0B872h
18 mov es,ax
19 mov cx,3
20 mov bx,16
21 s:
22 push cx
23 mov cx,16
24 mov si,0
25 mov di,0
26 s0:
27 mov al,ds:[di]
28 mov ah,ds:[bx]
29 mov es:[si],ax
30 add si,2
31 inc di
32 loop s0
33
34 pop cx
35 mov ax,es
36 add ax,000ah
37 mov es,ax
38 inc bx
39 loop s
40
41 mov ax,4c00h
42 int 21h
43
44 code ends
45 end start

实验代码运行结果:

 2. 实验任务2

编写子程序printStr,实现以指定颜色在屏幕上输出字符串。调用它,完成字符串输出。

子程序printSar

功能:以指定颜色在屏幕上(从屏幕左上角开始)输出字符串要求:字符串以0结尾入口参数字符串的起始地址—> ds: si (其中,字符串所在段的段地址—> ds, 字符串起始地址的偏移地址—> si字符串颜色—> al出口参数:无

 1 assume cs:code, ds:data
2 data segment
3 str db 'try', 0
4 data ends
5
6 code segment
7 start:
8 mov ax, data
9 mov ds, ax
10
11 mov si, offset str
12 mov al, 2
13 call printStr
14
15 mov ah, 4ch
16 int 21h
17
18 printStr:
19 push bx
20 push cx
21 push si
22 push di
23
24 mov bx, 0b800H
25 mov es, bx
26 mov di, 0
27 s:
28 mov cl, [si]
29 mov ch, 0
30 jcxz over
31 mov ch, al
32 mov es:[di], cx
33 inc si
34 add di, 2
35 jmp s
36
37 over:
38 pop di
39 pop si
40 pop cx
41 pop bx
42 ret
43
44 code ends
45 end start

把line3改为:strdb 'another try', 0

改变了内容

把line12改为:mov al, 4

改变了字体颜色

基于运行结果,理解源代码,以及,组合使用转移指令call和ret实现子程序的原理与方法。

  • 具体地,在line18-40中:line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?

答:保留现场,将子程序运行前寄存器的值保留下来,运行结束后再还原,不干扰原程序的运行,不改变它的值。避免了程序间的冲突和错误。

  • line30的功能是什么?

答:将字符内容和它的颜色属性存入指定的显存中,打印到屏幕上。

3. 实验任务3

使用任意文本编辑器,录入汇编源程序task3.asm。

子程序num2str:功能:把0~2559之间的任意整数转换成数字字符串,

例如,把1984转换成'1984'入口参数要转换的整数 —> ax数字字符串的起始地址 —> ds:di (其中:数字字符串所在段的段地址—> ds,字符串起始地址的偏移地址—>di)出口参数:无

 1 assume cs:code, ds:data
2 data segment
3 x dw 1984
4 str db 16 dup(0)
5 data ends
6
7 code segment
8 start:
9 mov ax, data
10 mov ds, ax
11 mov ax, x
12 mov di, offset str
13 call num2str
14
15 mov ah, 4ch
16 int 21h
17
18 num2str:
19 push ax
20 push bx
21 push cx
22 push dx
23
24 mov cx, 0
25 mov bl, 10
26 s1:
27 div bl
28 inc cx
29 mov dl, ah
30 push dx
31 mov ah, 0
32 cmp al, 0
33 jne s1
34 s2:
35 pop dx
36 or dl, 30h
37 mov [di], dl
38 inc di
39 loop s2
40
41 pop dx
42 pop cx
43 pop bx
44 pop ax
45
46 ret
47 code ends
48 end start

子任务1对task3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串'1984'存放在数据段中str标号后面的单元。

可以看到存入单元内。

子任务2

对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来, 实现对转换后的字符串进行输出。

把task3.asm源代码中,line3中整数改成0~2559之间的任意数值,运行测试,观察结果。

 4. 实验任务4

使用任意文本编辑器,录入汇编源程序task4.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
12 s1:
13 mov ah, 1
14 int 21h
15 mov [si], al
16 cmp al, '#'
17 je next
18 inc si
19 jmp s1
20 next:
21 mov cx, si
22 mov si, 0
23 s2: mov ah, 2
24 mov dl, [si]
25 int 21h
26 inc si
27 loop s2
28
29 mov ah, 4ch
30 int 21h
31 code ends
32 end start

运行结果:

汇编、链接、运行程序,输入一个字符串并以#结束(比如,2020, bye#)观察运行结果。结合运行结果,理解程序功能,了解软中断指令。

具体地:line12-19实现的功能是?

答:利用软中断指令,int 21h中的1号子功能,将输入的字符串中“#”前的字符存储到指定的栈断中。

line21-27实现的功能是?

答:统计“#”前的字符个数作为循环次数,利用2号子功能在屏幕上输出。

5. 实验任务5

在visual studio集成环境中,编写一个简单的包含有函数调用的c程序。代码如下:

#include <stdio.h>
int sum(int, int);
int main() {
int a = 2, b = 7, c;
c = sum(a, b);
return 0;
}
int sum(int x, int y) {
return (x + y);
}

在line7, line13分别设置断点,在调试模式下,查看反汇编代码。

line7断点:

进入sum子函数中,line13断点:

分析反汇编代码,从汇编的角度,观察高级语言中参数传递和返回值是通过什么实现的,以及,参数入栈顺序,返回值的带回方式,等等。

答:高级语言中参数传递和返回值都是通过寄存器实现的。

参数入栈顺序自右向左,b的值传入寄存器eax,a的值传入寄存器ecx,之后使用call指令调用子函数sum

在函数内将结果存入了eax中。返回主函数中,eax的值传给c。

五、实验总结

1、进一步了解总结了之前实验中的显存区域输出,实际操作了课上讲解的内容,屏幕位置的具体计算。

2、了解和使用了软中断指令。

最新文章

  1. Android APP 简单高效的禁用横竖屏切换
  2. php开发(TP框架使用)
  3. Laravel 实现定时任务
  4. POJ 3299 Humidex(简单的问题)
  5. php扩展SeasLog应用于 yii2 组件
  6. 一个VB编写的俄罗斯方块
  7. 非Unicode编码的软件如何在Windows系统上运行
  8. 北京大学Cousera学习笔记--3-计算导论与C语言基础-第一讲.计算机的基本原理-计算机怎么计算-数的二进制
  9. 在python3里面使用ueditor(基于adminx)
  10. celery (二) task
  11. Elasticsearch&#160;Search&#160;APIs
  12. 水题:P2799 国王的魔镜
  13. input &amp; collapse &amp; tags
  14. 关于CPU的User、Nice、System、Wait、Idle各个参数的解释
  15. Axure快速原型教程02--创建页面和设置界面
  16. NSNotificationCenter实现原理
  17. springboot form 提交集合 list
  18. LDAP Error Codes
  19. MapReduce编程基础
  20. 关于对afx_msg的解释-----来源百度百科

热门文章

  1. 考研党其实可以用思维导图MindManager做考研复习计划
  2. 免费在线使用Ayoa:让思维导图更简单
  3. 通过Camtasia来添加各种各样的光标效果
  4. 用思维导图软件iMindMap来提高记忆
  5. Vegas转场功能的妙用,让片头转场更酷炫
  6. python中操作excel数据
  7. Java命令行启动jar包更改默认端口以及配置文件的几种方式
  8. 这份SpringMVC执行原理笔记,建议做java开发的好好看看,总结的很详细!
  9. Leetcode 周赛#201 题解
  10. D. Circle Game 题解(对称博弈)