鱼C论坛

 找回密码
 立即注册
查看: 1771|回复: 0

[技术交流] 用了一下午做的王爽 汇编实验十(1) 我个人觉得注释已经很全面了。 求交流。

[复制链接]
发表于 2012-10-15 17:04:44 | 显示全部楼层 |阅读模式

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

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

x
首先。声明,本人昨天才完成第十章的学习。。纯菜鸟一个。有不好的地方还请勿喷。当然。有需要优化的地方,希望各位大神指出。
不过类似赞美神马的,,当然是有多少来多少了。。小子不介意。好了。废话不多说。上题上源码。

完成子程序。
名称:show_str
功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:(dh)=行号(取值范围0~24);
      (dl)=列号(取值范围0~79);
      (cl)=颜色;
       ds:si指向字符串的首地址。返回:无
应用举例:在屏幕的8行3例,用绿色显示data段中的字符串。
assume cs:code,ds:data
data segment
    db 'welcome to masm!',0
data ends
code segment
start:   mov dh,8
     mov dl,3
    mov cl,2
     mov ax,data
     mov ds,ax
     mov si,0
     call show_str


     mov ax,4c00h
     int 21h
show_str:……
code ends
end start



下面是我写好的源码:
assume cs:code

data segment
                db 'Welcome to masm!',0
data ends

stack segment
                dw 8 dup (0)
stack ends

code segment
start:   mov dh,8             ;定义第N行。
                 mov dl,3             ;定义第N列。
                 
                 mov cl,2             ;定义字符串颜色。
                 
                 mov ax,data         
                 mov ds,ax            ;将需要显示的字符地址定义为数据段地址。
                 mov si,0             ;定义数据段偏移.
                 
                 mov ax,stack         
                 mov ss,ax
                 mov sp,10h           ;定义一个栈,用于存放数据。
                 

                 call show_str        ;调用子程序,实现字符串的显示.
                 
                 mov ax,4c00h
                 int 21h              ;调用完毕,退出程序.
                 
show_str:push ax
                 push es
                 push di
                 push bx              ;将本段子程序会用到的,而上面没有强制要求的数据存入栈。以免影响其他子程序的执行与调用。
                 
                 mov ax,0b800h
                 mov es,ax            ;将显存段段地址存入ES,以便后面数据的存储.
                 
                 mov al,160           ;定义每字节单元数量,用于计算定义行起始位置(因为每一行有160个字节单元,列数:0到24 永远为8位,故此处使用8位做"mul")
                 mul dh               ;用定义行乘行长度,计算出第N行起始位置。
                 mov bx,ax            ;将乘法结果(第N行起始位置)放入BX中作为偏移.
                 
                 mov al,2             ;显存段里每个显示数据占两个字节空间(为计算定义列做准备).
                 mul dl               ;用定义列乘以列宽度,计算出第N列的起始位置.
                 mov di,ax            ;将乘法结果(第N列起始位置)放入di中指向每次要执行数据写入的内存地址空间。
                 
           s:push cx              ;将CX的值推入栈,以便判断时寄存器的值变化后取出继续调用.
                 
                 sub cl,cl            ;将CL置零,以便接下来的"jcxz"判断.
                 mov ch,[si]          ;将需要操作的数据置入CH中,用于接下来的判断.
                 jcxz ok              ;判断是否完成对数据的操作,如果完成跳转,未完成则继续执行.
                 
                 pop cx               ;取出CX在判断准备之前存入栈的值.
                 mov ch,[si]          ;由于取出时会覆盖ch的值,所以将数据的ASCⅡ码再次置入CX,以便接下来的转存.
                 
                 mov es:[bx+di],ch    ;将需要显示的数据的ASCⅡ码存入需要操作的位置.
                 mov es:[bx+di+1],cl  ;将数据需要显示的颜色置入相应的位置.
                 
                 inc si               ;si指向下一个需要操作的数据.
                 add di,2             ;bx+di指向下一个需要操作的位置.
                 
                 jmp near ptr s       ;跳转至S标号处再次执行此操作.直至"JCXZ"跳转为止.
                 
          ok:pop bx
                 pop di
                 pop es
                 pop ax               ;取出子程序开始时存入栈中的数据.
                 ret                  ;子程序结束,返回call后面继续执行.
code ends
end start


好了。就是这样。。。有需要精简的请指出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-18 14:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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