汇编语言随笔(8)-实验9(显示字符串)、实验10(子程序:除法溢出,数值到字符串的转换)和课程设计1
实验9
编程,在屏幕中间分别显示绿色,绿底红色,白底蓝色的字符串‘welcome to masm!’。
80x25彩色字符模式下的显示缓冲区,每页可以显示25行,每行80个字符,其中每个字符占两个字节的存储空间,低位字节存储字符的ASCII值,高位字节存储字符的属性。所以一行总共有160个字节。其中属性字节的格式如下:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|
含义 | BL | R | G | B | I | R | G | B |
其中BL为闪烁,R为红色,G为绿色,B为蓝色,I为高亮,在高位的RGB表示背景颜色,低位的表示前景颜色。
以绿底红色为例,它的颜色属性为00100100B。显示缓冲区的段地址为0b800h,默认在第0页的屏幕中间的偏移地址为12x160+(40-16/2)x2。其中16为本程序中字符串的字节数。搞清楚了目的地址和颜色属性之后,我们开始编写程序:
assume cs:codedata segmentdb 'welcome to masm!'data endscode segmentstart:mov ax,0b800hmov es,axmov di,12*160+32*2 目的地址存储在es:di中mov ax,datamov ds,axmov bx,0mov cx,10hs: mov al,[bx]mov es:[di],almov byte ptr es:[di+1],00100100Binc bxadd di,2loop smov ax,4c00hint 21hcode endsend start
实验10
问题1 显示字符串
编写一个通用的子程序来让调用者可以决定显示的位置(行、列、内容和颜色)
子程序描述如下:
名称:show_str
功能:在指定的位置、用特定的颜色,显示一个用0结束的字符串
参数:(dh)=行号(取值范围为0-24),(dl)=列号(取值范围为0-79),(cl)=颜色,ds:si指向字符串的首地址
返回:无
在屏幕的8行3列,用绿色显示data段中的字符串,完整的程序如下:
assume cs:codedata segmentdb 'Welcome to masm!',0data endscode segmentstart: mov dh,8mov dl,3mov cl,2mov ax,datamov ds,axmov si,0call show_strmov ax,4c00hint 21hshow_str: push cxpush dxpush axpush sipush dspush dipush esmov ax,0b800hmov es,axmov di,dh*160+dl*2 es:di为目的地址s: mov al,[si]cmp al,0je donemov es:[di],almov es:[di+1],cladd di,2inc sijmp short sdone: pop espop dipop dspop sipop axpop dxpop csretcode endsend start
问题2 解决除法溢出
问题:除法溢出指的是商过大,超出了寄存器的存储范围。比如:16位的被除数和8位的除数在做除法的时候,用al存储结果的商,ah存储结果的余数。如果当除数为1时,那么商也是一个16位数据,这超过了al这个8位寄存器所能表示数据的范围了。
子程序描述如下:
名称:divdw
功能:进行不会溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,(cx)=除数
返回:(dx)=结果的高16位,(ax)=结果的低16位,(cx)=余数
提示:参考公式如下:
X:被除数,范围:[0,FFFFFFFF]
N:除数,范围:[0,FFFF]
H:X高16位,范围:[0,FFFF]
L:X低16位,范围:[0,FFFF]
int():描述性运算符,取商,比如,int(38/10)=3
rem():描述性运算符,取余数,比如,rem(38/10)=8
公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
注意:乘以65536相当于左移16位。
计算1000000/10(F4240H/0AH)完整程序如下:
assume cs:codedata segmentdw 4 dup(0)data endscode segmentstart: mov ax,datamov ds,axmov si,0mov ax,4240hmov dx,0fhmov cx,0ahcall divdwmov ax,4c00hint 21hdivdw: push dspush sipush cxpush axpush dxmov [si],ax 保存被除数的低16位Lmov [si+2],dx 保存被除数的高16位Hmov ax,dxmov dx,0div cx 用高16位H除以除数Nmov [si+4],ax 保存商mov ax,[si]div cx rem(H/N)作为高16位,L作为低16位,除以Nmov [si+2],axmov [si],dx//将商的高16位存储在[si+4]处,低16位存储在[si+2]处,余数存储在[si]处。done: pop dxpop axpop cxmov cx,[si] 保存返回值到相应的寄存器中mov ax,[si+2]mov dx,[si+4]pop sipop dsretcode endsend start
问题3 数值(int)到字符串形式的转换
问题:把数据用十进制的形式显示到屏幕上,需进行两步的操作:(1),将用二进制信息存储的数据转变为十进制形式的字符串(2),显示十进制形式的字符串(只需调用问题1的show_str即可)
子程序描述如下:
名称:dtoc
功能:将word型数据转变为十进制数的字符串,字符串以0为结尾符。
参数:(ax)=word型数据、ds:si指向字符串的首地址
返回:无
编程,将数据12666以十进制形式在屏幕的8行3列,用绿色显示出来。在显示时调用本次实验中的第一个子程序show_str。
思路:想要得到十进制数12666的每一位数值,需将12666除以10,它的余数6为个位上的数值,它的商1266作为新的被除数再除以10,余数6为原数据十位上的数值,它的商再次除以10,以此类推,进行5次除以10操作就可以得到每一位的值了。
在已知数据为12666的情况下,循环次数为5,但对于数据未知的情况下,就需要判定每次得到的商是否为0了,当除到商为0时,所有位上的值就被全部求出。在此采用jcxz指令来实现此功能。
除法功能在此采用32位除以16位的方式来实现,因为这样不会导致溢出。因为如果采用16位除以8位的方式的话,那么它的商也是用8位来保存的,而12666/10=1266,这已经大于8位数据的最大值255了。
assume cs:codedata segmentdb 10 dup(0)data endscode segmentstart: mov ax,12666mov bx,datamov ds,bxmov si,0call dtocmov dh,8mov dl,3mov cl,2call show_str mov ax,4c00hint 21hdtoc: push bxpush cxpush axpush dxmov bx,10 整数10作为16位的除数放在bx中mov si,9mov byte ptr [si],0 字符串末尾置0sub si,1s: mov dx,0div bxadd dl,'0' 容易看出dh中全为0,计算出数据的实际ASCII值mov [si],dl 字节单元数据的传送,将余数保存到内存中mov cx,axjcxz donesub si,1jmp short sdone: pop dxpop axpop cxpop bxretcode endsend start
课程设计1
将实验七中的公司21年的数据在屏幕上显示出来,一共占据屏幕21行,每一行中显示出每一年的数据,依次为年份、收入、雇员数和平均收入。
思路:
先计算出每一字段的行号和列号,可得,行号范围为[2,22];每一行第一个字段起始地址为6,第二个字段起始地址为28,第三个字段起始地址为50,最后一个字段起始地址为72。这样就可以将所有数据内容显示在屏幕中央。
说明一点,前面已经实现了的子程序在此将被直接调用。
但还需要编写一个将dword型数据转换为字符串的子程序。说明如下:
名称:ddtoc(为了和word型数据转换子程序dtoc区分开来)
功能:将dword型数据转变为表示十进制数的字符串,字符串以0为结尾符
参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,ds:si指向字符串的首地址
返回:无
仍需要注意除法溢出的问题。
完整程序如下:
assume cs:codedata segamentdb '1975','1976','1977','1978','1979','1980','1981','1982','1983'db '1984','1985','1986','1987','1988','1989','1990','1991','1992'db '1993','1994','1995'//用21个字符串来表示年份dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514dd 245980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000//用21个双字型数据来表示公司每年的总收入dw 3,7,9,13,28,38,130,220,476,778,100,1442,2258,2793,4037,5635,8226dw 11542,14430,15257,17800//用21个字型数据来表示公司每年的员工数量data endsbuf segmentdb 16 dup(0) 这块内存是用来进行双字型到字符串转换的buf endscode segmentstart:mov ax,datamov ds,axmov bx,0 ds:bx表示数据段起始的偏移地址mov ax,0b800hmov es,ax mov di,160*2 es:di指向显示缓冲区第二行第0列mov al,21mov dl,8mul dlmov si,ax 计算21*8,保存到si中,这是雇员数在数据段的起始偏移地址mov cx,21 外层循环次数21次body: mov ax,[bx]mov es:[di+6],axmov ax,[bx+2]mov es:[di+8],ax 年份push sipush dsmov ax,[bx+84]mov dx,[bx+86]call ddtocmov bp,0subb: mov al,[si]cmp al,0je nextmov es:[di+bp+28],alinc bpinc sijmp short subb 总收入next: pop dspop simov ax,[si]push dspush simov ax,bufmov ds,axcall dtocmov bp,0subbo: mov al,[si]cmp al,0je nnextmov es:[di+bp+50],alinc bpinc sijmp short subbo 雇员数 nnext: pop sipop dsmov dx,[bx+86]mov ax,[bx+84]div word ptr [si] 计算人均收入push dspush simov ax,bufmov ds,axcall dtoc 字型数据转换为字符串mov bp,0
subbody:mov al,[si]cmp al,0je nnnextmov es:[di+bp+72],alinc bpinc sijmp short subbody nnnext: pop sipop dsadd di,160add si,2add bx,4loop bodymov ax,4c00hint 21hddtoc: push cxpush axpush dxmov ax,bufmov ds,axmov si,15mov byte ptr [si],0dec sis: mov cx,10 除数10保存在cx中push simov si,0 将ds:si开始后的6个字节作为divdw中的临时缓存call divdw divdw采用本文中实现的子程序pop siadd cl,'0'mov [si],cldec sicmp dx,0jne scmp ax,0je donejmp short sdone: inc si 注意,最后退出时si并不是刚好指向字符串首地址pop dxpop axpop cxretcode endsend start
汇编语言随笔(8)-实验9(显示字符串)、实验10(子程序:除法溢出,数值到字符串的转换)和课程设计1相关推荐
- 微型计算机原理实验报告系统认识,微机原理 实验报告——显示程序实验与8259应用编程实验...
微机原理 实验报告--显示程序实验与8259应用编程实验 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 11.9 积分 北京信息科技大学自动化学院实 ...
- 汇编语言实现七段数码管显示控制实验
一 实验目的 1)掌握8255方式0的工作原理.初始化设置方法. 2)掌握I/O接口地址译码电路的工作原理及端口地址的计算方法. 3)掌握I/O端口的读写操作及编程方法. 4)掌握数码管显示数字的原理 ...
- 7-3 字符串替换 (10分)(Java,超长字符串替换创建快速输入流)
// package test;// 3 //这输入输出就离谱 import java.io.BufferedReader; import java.io.IOException; import ja ...
- 计算机组成原理课程设计总结,计算机组成原理课程设计的实验报告
计算机组成原理课程设计的实验报告 长治学院课程设计报告课程名称: 计算机组成原理课程设计 设计题目: 设计一台性能简单的计算机 系 别: 计算机系 专 业: 计科1101班 组 别: 第三组 学生姓名 ...
- c语言程序设计报告表达式求值,数据结构 课程设计表达式求值 实验报告
<数据结构 课程设计表达式求值 实验报告>由会员分享,可在线阅读,更多相关<数据结构 课程设计表达式求值 实验报告(21页珍藏版)>请在人人文库网上搜索. 1.实验课程名称 级 ...
- java数组转为字符串_join()和toString()方法 将数组转换为字符串
join()方法将数组中所有的元素转化为字符串,并将这些字符串有逗号隔开合并成一个字符串作为方法的结果返回.如果调用时给定参数string,就将string作为在结果字符串中分开有各个数组元素形成的字 ...
- lisp 提取字符串中的數字_Redis 数据结构之字符串的那些骚操作
Redis 字符串底层用的是 sds 结构,该结构同 c 语言的字符串相比,其优点是可以节省内存分配的次数,还可以... 这样写是不是读起来很无聊?这些都是别人咀嚼过后,经过一轮两轮三轮的再次咀嚼,吐 ...
- PTA字符串压缩 (10 分)
字符串压缩 (10 分) 本题要求实现一个字符串压缩的简单函数.压缩规则是:如果某个字符x连续出现n(n>1)次,则将这n个字符x替换为nx的形式:否则保持不变. 函数接口定义: void zi ...
- 汇编语言随笔(11)- int 指令(返回到应用程序的中断例程),实验13(编写、应用中断例程)
int 指令 int 指令的格式为:int n,n为中断类型码.这里由 n 显式的给出了调用哪一个中断处理程序. CPU 的中断过程仍然是: (1)取中断类型码n (2)标志寄存器入栈,I ...
最新文章
- software reporter tool占用高_广安市园林车载高射程雾炮机厂家供货
- 自己写的一个tomcat发布脚本
- (iOS)Storyboard/xib小技巧
- Python爬虫开发:requests库的使用--session的使用
- UIAutomation识别UI元素
- 309. Best Time to Buy and Sell Stock with Cooldown 最佳买卖股票时机含冷冻期
- 5. OD-把限制的功能恢复,把阉割的功能添加(未注册版本,部分功能不可使用的修改)
- js 将多个对象合并成一个对象
- python借助missingno可视化分析缺失值
- GIS:揭开你神秘的面纱
- 易语言单窗口单ip软件源码_游戏搬砖怎样换IP防封?有几种处理方法?
- sata电源定义 联想小4pin_SATA硬盘15针供电接口的引脚定义
- 三合一收款码在线生成艺术创意的二维码网站源码 多模板
- EXCEL中的定位条件(含快速删除空行,定位图片、文本框等对象)
- MySQL8.0局域网共享
- Java分别获取指定日期的年月日
- SQLMAP进阶:参数讲解
- 构建开发环境 构建demo_构建自己的wotsapp第6部分
- 微软再曝“丑闻”:在办公室看 VR 黄片,“HoloLens 之父”即将离职!
- https://maven.google.com不能访问解决办法!
热门文章
- Salesforce - soql 多字段多值过滤查询思路
- 图论数学:矩阵树定理
- L1-046. 整除光棍(模拟除法)
- JS事件冒泡机制和兼容性添加事件
- delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树
- 转载:QT图形视图框架(The Graphics View Framework)
- 用boolalpha输出true或false的问题
- MyEclipse 7.5优化
- 关于java的对象数组
- 在python中查看关键字需要在python解释器中执行_现有代码 d={},在Python3解释器中执行 d[([1,2])] = 'b'得到的结果为( )。...