. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验十 (1) 我觉得我写的比较规范了!  [待解决] 回复[ 8次 ]   点击[ 470次 ]  
zhenglxd
[帖 主]   [ 发表时间:2009-05-15 11:02 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
assume cs:code,ss:stack
data segment
  db 'welcome to masm!',0
data ends
stack segment
  dw 20 dup (0)
stack 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: mov ax,stack ;指定栈段,状态栈空
            mov ss,ax
            mov sp,40 

            push ax       ;寄存器原始数据用栈备份
            push bx
            push cx
            push dx
            push si

            mov bx,0       ;数据初始化
            
            mov ax,0b800H    ;确定显存所在段
            mov es,ax

            mov al,160     ;确定显存起始偏移地址
            dec dh
            mul dh
            mov dh,0
            add dl,dl      ;列偏移地址
            add ax,dx      ;行偏移地址加列偏移地址
            mov bx,ax      ;bx表示起始偏移地址
            mov al,cl      ;al表示颜色

            mov ch,0       ;counter高位清0
         s: mov cl,ds:[si] ;用cl检字符窜是否为0
            jcxz s1        ;如果为0,程序转移到s1
                           ;不为0执行下列程序

            mov es:[bx],cl   ;字符ASCII码写入显存地址
            mov es:[bx+1],al ;字符属性写入显存地址  
            inc si           ;si定位字符窜ASCII偏移地址
            add bx,2         ;bX定位写入显存的偏移地址
            loop s           ;循环
            
       s1:  pop si           ;相关寄存器数据还原
            pop dx
            pop cx
            pop bx
            pop ax

            ret              ;返回调用程序

code ends
end start
escapestool
[第1楼]   [ 回复时间:2009-05-16 19:25 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-04-28 23:57
这么长,来个短点的
assume cs:code
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:mov al,160
         mul dh
         mov dh,0
         add ax,dx
         mov bx,ax
         mov ax,0b800h
         mov es,ax
         mov di,0
         mov ah,cl
 s:      mov al,[si]
         mov word ptr es:[bx+di+1],ax
         mov ch,0
         mov cl,al
         jcxz ok
         add si,1
         add di,2
       jmp short s
  ok: ret
                

code ends 
end start
zhenglxd
[第2楼]   [ 回复时间:2009-05-17 10:30 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
你所谓的短 就是 少几行空格 以及 不做寄存器原始数据备份和恢复啊 狂汗
cfcxg
[第3楼]   [ 回复时间:2009-06-11 16:31 ]   [引用]   [回复]   [ top ] 
荣誉值:9
信誉值:3
注册日期:2008-12-21 10:26
呵呵,短是没短多少,不过有值得学习的地方,还有我觉得楼主的LOOP指令用得没有JMP恰当
hhquan
[第4楼]   [ 回复时间:2009-06-13 10:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-06-12 14:58
自己也写了一个,不过不规范,没怎么注释。
DATAS SEGMENT
    db 'welcome to masm!',0
DATAS ENDS

STACKS SEGMENT
    
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    mov dh,8
    mov dl,3
    mov cl,2
    call show_str
    
    MOV AH,4CH
    INT 21H
    
    
show_str:
        mov ax,0b800h ;定义显示位置
        mov es,ax
        mov al,160
        mul dh
        add dl,dl
        add al,dl
        mov bx,ax
        
        mov si,0
        mov di,0
        push dx
        mov ch,0
        push cx
        pop dx
s:
        mov cl,[si]
        jcxz ok
        mov ah,dl
        mov al,cl
        mov es:[bx+di],ax
        inc si
        add di,2
        loop s
ok:        
        mov cx,dx
        pop dx
        ret
CODES ENDS
    END START
abcdwzxy
[第5楼]   [ 回复时间:2009-06-22 02:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:3
注册日期:2009-03-13 16:19
楼主 我仔细看了你的程序,我想请问你,你在计算行偏移的时候加上了一句 "dec dh"也就是将行数减一再去乘160,你有没有仔细去数过你的程序显示真的是在第8行吗?恐怕应该在第7行吧!

我当初做的是和你一样的,计算的时候也加上了一句"dec dh" 就始终不能再正确的位置显示!
zhenglxd
[第6楼]   [ 回复时间:2009-06-23 09:51 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
对于对象 我们来说 1~9 对应的是屏幕上 1~9行
对于 cpu来说 0才是他的第一行 所以要在 屏幕上第一行显示 必须输入的行数-1
zhy_zhy
[第7楼]   [ 回复时间:2009-07-26 13:15 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:2
注册日期:2009-06-29 14:39
楼主这里不能用loop吧,不然如果恰好碰到01h不是就出问题啦
advancedprogrammer
[第8楼]   [ 回复时间:2009-07-31 09:16 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:3
注册日期:2009-06-08 15:13
个人认为在子程序中忽略保护寄存器而追求代码短是一种错误的做法
assume cs:code,ds:data,ss:stack 

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

stack segment 
        dw 8 dup(0) 
stack ends 

code segment 
start:  mov dh,16        
        mov dl,50 
        mov cl,42       
        mov ax,data 
        mov ds,ax 
        mov ax,stack
        mov ss,ax
        mov sp,16
        mov si,0 
        call show_str       
         
        mov ax,4c00h 
        int 21h 
show_str:push ax
         push bx
         push cx
         push dx
         push es
         push di
         push ds
         push si
         
         mov ax,0b800h
         mov es,ax
         mov al,160
         mul dh
         mov bx,ax  ;bx中保存行
         mov dh,0 
         add dx,dx
         mov di,dx  ;di中保存列
         mov al,cl  ;al中保存颜色

      print: mov cl,[si]
         mov ch,0
         jcxz out
         mov es:[bx+di],cl
         mov es:[bx+di+1],al
         inc si
         add di,2
         jmp short print
     out:pop si
          pop ds
          pop di
          pop es
          pop dx
          pop cx
          pop bx
          pop ax
          ret
               
code ends 
end start
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved