鱼C论坛

 找回密码
 立即注册
查看: 2360|回复: 3

[汇编作业] 实验10第一个程序解题思路,欢迎交流

[复制链接]
发表于 2015-6-30 00:03:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 glider 于 2015-6-30 00:09 编辑

QQ截图20150629230819.bmp 这个问题实质上很简单,只要把需求搞清楚,转化为思路,剩下的就是写代码和调试代码了。
我们先看题目的要求,有2个:
        1. 读取data段中的字符,设置样式
        2. 把设置好样式的字符,写入到指定位置的显存中
那么我们的初步思路就应该是这样的:
        第一步,读取数据。读取data段中的数据,遇到0表示字符结束,这个应该不用再说了吧。
        第二步,处理数据,即设置样式。添加了显示样式的数据占两个字节,所以在第一步中,我们最好把数据读到一个reg的低位中,然后在这一步里,把样式(在cl中)写入到reg的高位。这一步也没有什么难点。
        第三步,写入显存。这是最关键的一步。把reg的内容显示在(dh)行、(dl)列,这个位置对应的内存地址,还需要我们自己去计算出来。显存所在的位置,实验9的题目介绍中已经详细说明了,这里不再缀述。
再要看上面的思路,读取数据、处理数据、写入数据可以放在一起,但是计算显示的位置,最好是单独拿出来,这样我们需要至少2个子程序:计算显示位置、把数据处理后显示出来;另外,主程序必不可少,它是整个程序的入口。我通常的写法是这样的:
        main:        主程序,初始化参数
                        
                        调用子程序sub1……
                        调用子程序sub2……
                        ……
                        
                        mov ax, 4c00h
                        int 21h

        sub1:        子程序1
        sub2:        子程序2
        ……


这个题目也不例外,看代码:
assume cs:code
data segment
        db 'welcome to masm!', 0
data ends
code segment
       main:                             ;参数初始化
               mov dh, 8              ;字符显示在哪一行
               mov dl, 3               ;字符显示在哪一列
               mov cl, 2               ;字符的样式
               mov ax, data         ;初始化数据段地址,数据地址用ds:[si]表示
               mov ds, ax
               mov si, 0        
               mov ax, 0b800h    ;初始化显示位置的段地址,显示地址用es:[bx]表示
               mov es, ax

               call show_str         ;调用在指定位置显示指定样式字符的方法

               mov ax, 4c00h        
               int 21h

      show_str:                      ;方法:在指定位置显示指定样式的字符
              call addr               ;调用方法:计算字符应该在哪个地址显示  参数1:行号dh,参数2:列号dl,计算结果存储在bx中
              call show              ;调用方法:将字符显示在计算好的位置  参数1:字符原地址ds:[si],参数2:字符显示位置es:[bx],参数3:字符样式cl
              ret
        
     show:  push cx                ;方法:读取数据段中的每一个字符,设置样式后,写入到显存中显示出来;参数1:字符原地址ds:[si],参数2:字符显示位置es:[bx],参数3:字符样式cl
                push ax                
                s:      mov ah, cl        ;先把字符的样式从cl转存到ah
                        mov cl, [si]        ;判断数据段是否读到0,如果读到0,从当前方法中返回
                        mov ch, 0
                        jcxz ok
                        mov al, cl        ;把字符内容转存到al,这个时候ax中包含了字符的样式和内容
                        mov es:[bx], ax        ;把字符内容和样式写入显存,显示到屏幕
                        inc si                
                        add bx, 2        
                        mov cl, ah        ;把字符样式还原回cl中
                        jmp s                
        ok:           pop ax                
                        pop cx
                        ret 

        addr:        push ax                ;方法:计算字符应该在哪个地址显示; 参数1:行号dh,参数2:列号dl,计算结果存储在bx中
                push dx                ;计算方法:80(字)*2(byte/字)*行号dh(0~24) + 列号dl*2(byte/列)
                mov al, 160        
                mul dh                
                mov dh, 0        ;把dh置为0,(dx) = (dl),这时候dx就是列号,方便与ax相加
                add ax, dx        ;因为每列2字节,所以列号要加两次
                add ax, dx
                mov bx, ax        ;把计算好的字符显示位置的偏移地址,存到bx中
                pop dx
                pop ax
                ret

code ends
end main
上面是我今天写的程序,时间太晚,明天还要早起上班,就不再优化了,各位如果有更好的思路,或者更优的处理方式,欢迎交流。重要表情发三遍:lol::lol::lol:






想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-6-30 13:54:29 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-6-30 14:15:04 | 显示全部楼层
点个赞
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-30 23:55:48 | 显示全部楼层
谢谢LZ分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-19 01:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表