. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  ■■■■■■■■■■■■■■■■实验 10.1    万用子程序 (指定位置输出字符与颜色)  [待解决] 回复[ 6次 ]   点击[ 417次 ]  
stop1204
[帖 主]   [ 发表时间:2013-05-20 08:39 ]   [引用]   [回复]   [ top ] 
荣誉值:424
信誉值:0
注册日期:2013-04-08 10:06
;子程序名称:show_str
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数:(dh)=行号(取值范围0-24);(dl)=列号(取值范围0-79);(cl)=颜色,ds:si指向字符串的首地址
assume cs:code
data segment
        db 'Welcome to masm!',0 ;要输出的字符与结束标志值"0"
data ends
code segment
start:        ;使用时只需要修改 dh,dl,cl 的值即可
        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:        
                push dx                ;暂存dx
;______        位置计算
                add dh,3        ;dh要另外+3,因为会被新输入的指令画面顶掉
                mov al,0AH
                mul dh
                mov ah,0b8H        ;颜色位置
                mov es,ax        
                mov al,2
                mul dl
                mov si,ax        ;第三列字符处 (1列2个字符[字符码 颜色码])        
;______        初始化
                mov bx,0
show:
;______        传递数据
                mov al,[bx]
                mov es:[si],al
                mov es:[si].1,cl;00000010b绿色
;______        检测        
                push cx                ;暂存颜色值
                mov ch,0
                mov cl,al
                jcxz ok                ;循环完成↓跳转 ok
                pop cx                ;还原颜色值
                inc si
                inc si
                inc bx
                jmp short show        ;或jcxz show
ok:        
                pop dx                ;还原dx
                ret                ;跳出子程序
code ends
end start

;说明:程序运行完成,输出welcome to masm!不在第8行,因为被向上刷新了,所以需要另外+3行
lonelyhover
[第1楼]   [ 回复时间:2013-05-21 14:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-07-18 20:29
保护现场不完整,CX和SI均未得到有效保护。
lonelyhover
[第2楼]   [ 回复时间:2013-05-21 14:58 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-07-18 20:29
mov ax,0b800h                                ;mov al,0ah
    mov es,ax        ;定位显存                                ;mul dh
    mov al,0a0h                                        ;add ax,0b800h
    mul dh                                        ;mov es,ax
    mov bx,ax        ;设置行号                                ;mov al,2h
    mov al,2h                                        ;mul dl
    mul dl                ;设置列号                        ;mov bx,ax
    add bx,ax        ;设置显示位置基址                ;减少一行指令,节省3字节空间,重定位显示位置需要重新修改段寄存器
    mov al,cl        ;设置字体属性
=========================================================================================
这是我的两种对显存定位的算法,希望可以一起讨论下咱俩的算法。
lonelyhover
[第3楼]   [ 回复时间:2013-05-21 15:01 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-07-18 20:29
mov al,0ah
mul dh
add ax,0b800h
mov es,ax
mov al,2h
mul dl
mov bx,ax
;与第一种相比减少一行指令,节省3字节空间。但是重定位显示在第八行之前的位置时需要重新修改段寄存器,在本程序中虽然不涉及,但是在某些情况下对于程序升级和通用性可能会有一定影响。
==============================================================
第二种,重新排版。
stop1204
[第4楼]   [ 回复时间:2013-05-23 08:17 ]   [引用]   [回复]   [ top ] 
荣誉值:424
信誉值:0
注册日期:2013-04-08 10:06
回复:[第3楼]
------------------
想要节省字节我可以节很多,这个只是方便理解
而且你bx 没 初始化0  ,  传递数据里面的bx 你要从什么位置开始 

要跟其他程序结合的时候自己加上保护就行了.
lonelyhover
[第5楼]   [ 回复时间:2013-05-23 13:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-07-18 20:29
想要节省字节我可以节很多,这个只是方便理解
而且你bx 没 初始化0  ,  传递数据里面的bx 你要从什么位置开始 

要跟其他程序结合的时候自己加上保护就行了.
------------------
回复:为什么要初始化BX为零呢 BX只是作为一个地址指针使用的,而其值首先有AX将行地址赋予,然后再加上列地址修正。之后其值就是所有输出的位置的地址。我不明白这里面为什么需要初始化为零。
stop1204
[第6楼]   [ 回复时间:2013-05-24 00:01 ]   [引用]   [回复]   [ top ] 
荣誉值:424
信誉值:0
注册日期:2013-04-08 10:06
回复:[第5楼]
------------------
你要跟其他程序结合时候 bx 原本不是0 呢 
那你一开始定位的第一个字符位置就找不到了
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved