. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验10.3显示数值搞定,子程序比答案少用了8条指令解决问题,请大家指教  [待解决] 回复[ 2次 ]   点击[ 332次 ]  
zhihuimao
[帖 主]   [ 发表时间:2009-06-03 20:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-27 19:28
assume cs:code,ds:data

data segment
   db 8 dup (0)            ;定义要显示的字符在内存中的位置
data ends

code segment
start:
  mov ax,data
  mov ds,ax

  mov ax,12666             ;要显示的word型数据送到ax中
  mov si,0
  call dtoc                ;调用子程序dtoc把word型数据转换成ascii码格式,保存到内存中相应位置

  mov dh,8
  mov dl,3
  mov cl,2
  mov si,0
  call show_str            ;调用show_str子程序,把内存中保存的ascii码在显存中显示出来

  mov ax,4c00h
  int 21h

;子程序名:show_str
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
;入口参数:(DH)=行号(取值范围0~24),(DL)=列号(取值范围0~79),
;          (CL)=颜色,DS:SI指向字符串的首地址
;返回参数:无

show_str:
  push cx                   ;保护CX
  push si                   ;保护SI
  mov ax,0b800h             ;设定附加段起始地址为彩色字符显示缓冲区
  mov es,ax 

  mov al,0a0h               ;定义行的长度
  mov ah,0                  
  mul dh                    ;计算要显示字符的行的起始地址
  mov bx,ax
  mov al,2                  
  mul dl                    ;计算出要显示的字符在行中的便宜
  add bx,ax                 ;计算出要显示的第一个字符在彩色字符缓冲区的位置
  mov dl,cl
  mov di,0

s:mov cl,ds:[si]            ;取出数据段的字符
  mov ch,0
  jcxz ok                   ;若取出的字符为0,则转到OK执行返回操作
  mov ch,dl                 ;若不为0,则把dl中保存的颜色字符放到ch寄存器
  mov es:[bx+di],cx         ;把第一个字符和其颜色属性一起送到彩色字符缓冲区中显示
  inc si                    ;si加1,准备取下一个字符
  add di,2                  
  jmp short s               ;跳转到s循环操作下一个字符

ok:pop si                   
   pop cx
   ret                      ;返回主程序,继续执行  

;子程序名称:dtoc
;功能:将word型数据转变成表示十进制数的字符串,字符串以0为结尾符。
;入口参数:(AX)=word型数据,DS:SI指向字符串的首地址
;出口参数:无

dtoc:
  push dx                  ;压栈保护dx、bx和cx寄存器中的值
  push bx
  push cx
  mov bx,10                ;设定除数为10                 
v:mov dx,0                 ;设定被除数的高16位为0
  div bx                    
  add dl,30h                ;把余数dx(肯定在dl中)转变为ascII码字符
  push dx                   ;把dx压栈,一遍逆序保存获得的ascii码
  inc si                    ;把获得的ascii码的个数加1
  mov cx,ax                 ;把商放到cx中
  jcxz w                    ;若cx(即商)为0,则转移到w标号处执行
  jmp v                     ;商不为0,跳转到v继续执行

w:mov cx,si                 ;把获得的ascii码的位数送到cx中,作为下一个循环的计数器
  mov si,0                  ;把si置0,以备循环保存ascii码
p:pop dx                    ;取出栈中保存的ascii码
  mov [si],dl               ;送到内存单元
  inc si                    ;变址指针加1
  loop p                    ;循环跳转到P处
  
  pop cx                    ;恢复子程序用到的寄存器值
  pop bx
  pop dx
  ret
  
code ends
end start
abcdwzxy
[第1楼]   [ 回复时间:2009-06-16 10:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:3
注册日期:2009-03-13 16:19
在最后是不是少了一句啊
要求是转变成字符,以‘0’结尾
应该在   loop p 后加上一句

mov ds:[si],0  (因为此时的si已指向了下一个内存单元了)
tsembrace
[第2楼]   [ 回复时间:2009-07-14 10:24 ]   [引用]   [回复]   [ top ] 
荣誉值:31
信誉值:3
注册日期:2009-06-15 19:20
把转字符程序中的除法改为类似实验10.2的防溢出的。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved