. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
主题 : :  我的子程序代码,大家也贴出自己的相互学习吧?  [待解决] 回复[ 7次 ]   点击[ 2037次 ]  
dontbend
[帖 主] [ 发表时间:2007-10-05 13:15 ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
assume cs:code

data segment
  db 10 dup (0)
data ends

stack segment
  db 16 dup(0)
stack ends;

code segment
start:
  mov ax,12666
  mov bx,data
  mov ds,bx
  mov si,0
  
  call dtoc
 
  mov dh,8
  mov dl,3
  mov cl,2
  call show_str
  mov ax,4c00h
  int 21h
dtoc:
  push cx
  push si
  push bx
  push dx
  push ds

  mov dx,0 
  mov bx,0 
  div_cur:  
    mov cx,0Ah 
    call divdw ;调用解决溢出的除法
    jcxz s  ;余数=0,跳出
    
    add cx,30H ;将余数转换成ASCII码 
    push cx
   inc bx
   jmp short div_cur
  
   s:
       mov cx,bx 
   s1:                                    
       pop ax       
       mov byte ptr ds:[si],al 
       inc si     
       loop s1   
    ok1:
       pop ds
       pop dx
       pop bx
       pop si
       pop cx
       ret
divdw:
    push bx

    push ax
    mov ax,dx
    mov dx,0
    div cx
    mov bx,ax ;将商的高位临时放到bx中
     pop ax
    div cx    ;上一步div的余数(在dx中)做高位,连同ax中的数据(低位)一起做被除数
     mov cx,dx ;将余数给cx
    mov dx,bx

    pop bx
    ret


show_str:
  push dx
  push cx
  push si
  push es
  push di
  push ax

  mov ax,0B800H
  mov es,ax
  mov ch,0

  ;计算dh*160,保存(dh*160)到di中
  mov ax,0A0H
  mul dh
  mov di,ax 

  ;计算2dl-1,保存(dh*160)+(2*dl-1)到di中,得到字符写入显存的偏移地址di
  mov ax,2
  mul dl
  add di,ax

  mov al,cl
  next_zf:    
    mov cl,[si]
    jcxz ok
    ;写入字符
    mov byte ptr es:[di],cl
    ;写入颜色
    mov byte ptr es:[di+1],al         
    add di,2
    inc si    
    jmp short next_zf
  ok:
    pop  ax
    pop  di
    pop  es
    pop  si
    pop  cx
    pop  dx
    ret

code ends
end start
dontbend
[第3楼] [ 回复时间:2007-10-06 17:43 ] 
荣誉值:0
信誉值:13
注册日期:2007-09-26 02:27
//修改后的,我的第一个存在问题,就是当数据末尾是零的时候会有问题


assume cs:code

data segment
  db 10 dup (0)
data ends

stack segment
  db 60 dup(0)
stack ends;

code segment
start:
  mov ax,12660
  mov bx,data
  mov ds,bx
  mov si,0
  
  call dtoc
 
  mov dh,8
  mov dl,3
  mov cl,2
  call show_str
  mov ax,4c00h
  int 21h


;功能:将数字转换成字符后显示在屏幕上
;要求数小于65535
;参数说明:(ds数转换成字符后存储的段地址,si偏移首地址,字符存储后的末尾要为0,
             ax存放dw数)
dtoc:
  push cx
  push si
  push bx
  push dx
  push ds
  push di

  mov dx,0 
  mov bx,0 
  mov di,0 
  
  div_cur:  
    mov cx,0Ah 
    call divdw ;调用解决溢出的除法
    mov bx,cx   ;因为商是存放在cx中的所以要求处理的数一定要小于65535
    mov cx,ax
    jcxz my_s  ;商=0,跳出
    
    add bx,30H ;将余数转换成ASCII码 
    push bx
    inc di  ;di用于累计余数压入栈的次数
    jmp short div_cur
  
   my_s:
       add bx,30H
       mov byte ptr ds:[si],bl
       mov cx,di 
       inc si
   s1:                                    
       pop ax       
       mov byte ptr ds:[si],al 
       inc si     
       loop s1   
   ok1:
       pop di
       pop ds
       pop dx
       pop bx
       pop si
       pop cx
       ret

;功能:避免溢出的除法
;公式:x/n=int(H/n)*65535+[rem(H/n)+L]/n
;参数:(ax,dd类型被除数的低位,dx高位,cx存放除数;)
;返回值:(dx,ax中放商,cx中放余数)
divdw:
    push bx

    push ax
    mov ax,dx
    mov dx,0
    div cx
    mov bx,ax ;将商的高位临时放到bx中
    pop ax
    div cx    ;上一步div的余数(在dx中)做高位,连同ax中的数据(低位)一起做被除数
    mov cx,dx ;将余数给cx
    mov dx,bx

    pop bx
    ret



;功能:在屏幕指定位置显示字符
;参数:(dh:行号,dl:列号,cl字符的颜色属性,ds:字符的段地址,si:段偏移首地址)
;调用:要求字符末尾以0结束
show_str:
  push dx
  push cx
  push si
  push es
  push di
  push ax

  mov ax,0B800H
  mov es,ax
  mov ch,0

  ;计算dh*160,保存(dh*160)到di中
  mov ax,0A0H
  mul dh
  mov di,ax 

  ;计算2dl-1,保存(dh*160)+(2*dl-1)到di中,得到字符写入显存的偏移地址di
  mov ax,2
  mul dl
  add di,ax

  mov al,cl
  next_zf:    
    mov cl,[si]
    jcxz ok
    ;写入字符
    mov byte ptr es:[di],cl
    ;写入颜色
    mov byte ptr es:[di+1],al         
    add di,2
    inc si
    jmp short next_zf
  ok:
    pop  ax
    pop  di
    pop  es
    pop  si
    pop  cx
    pop  dx
    ret


code ends
end start
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved