鱼C论坛

 找回密码
 立即注册
查看: 2644|回复: 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
        ……


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

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

  16.                mov ax, 4c00h        
  17.                int 21h

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

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

  27. code ends
  28. end main
复制代码

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






小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-6-30 13:54:29 | 显示全部楼层
{:1_1:}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-6-30 14:15:04 | 显示全部楼层
点个赞
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-30 23:55:48 | 显示全部楼层
谢谢LZ分享
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-3 09:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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