. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
主题 : :  实验10-3编写的程序找不到错误,请教大家(有详细说明)  [已解决] 回复[ 6次 ]   点击[ 599次 ]  
ztf770710
[帖 主] [ 发表时间:2010-04-27 15:26 ] 
荣誉值:4
信誉值:2
注册日期:2008-01-16 11:01
显示字符串和除法溢出2个子程序都经过验证的。程序如下:
assume cs:code

data segment
  db 10 dup (0)
data ends

stack segment
  dw 32 dup (0)
stack ends

code segment
start: mov ax,data
       mov ds,ax        ;设置ASC码存放空间
       mov ax,stack
       mov ss,ax
       mov sp,64        ;设置栈段
       mov si,0         ;设置首地址
       mov ax,12666
       mov dx,0         ;将数值的低16位送入ax,高16位送入dx,调用子程序转换为ASC码
       call dtoc        ;调用转换为ASC码子程序
       mov dh,8         ;输入行号
       mov dl,3         ;输入列号
       mov cl,2         ;输入颜色        
       call show_str    ;调用显示字符串子程序

       mov ax,4c00h
       int 21h

dtoc:  push ax
       push bx
       push cx
       push dx
       push si
       push ds          ;将子程序用到的寄存器入栈
       mov bx,0         ;设置计数器

  d0:  mov cx,10        ;除数为10
       call divdw       ;调用避免除法溢出子程序,商的高16位在dx中,低16位在ax中,余数在cx中
       add cx,30h       ;余数加30h,变为ASC码
       push cx          ;将余数ASC码入栈
       inc bx           ;计数器加1
       mov cx,dx        ;将商的的高16位移入cx
       jcxz d1          ;如果(cx)=0,转移到d1处;如果不是0,向下执行
       jmp near ptr d0  ;转移到d0处,继续做除法 

  d1:  mov cx,ax        ;将商的的低16位移入cx   
       jcxz ak          ;如果(cx)=0,转移到ak处;如果不是0,向下执行         
       jmp near ptr d0  ;转移到d0处,继续做除法

  ak:  mov cx,bx        ;将计数器的值存入cx

  bk:  pop ax           ;最后的余数ASC码出栈
       mov [si],al      ;将余数ASC码存入ds:si处
       inc si           ;si加1
       loop bk          ;如果(cx)=0,向下执行;如果不是0,转移到bk处,循环将栈中的余数ASC出栈
       mov [si],0       ;设置ASC码结束符,显示字符串子程序根据此符号判断字符串是否结束

       pop ds
       pop si
       pop dx
       pop cx
       pop bx
       pop ax           ;将子程序用到的寄存器出栈
       ret 

show_str: push es
          push ds
          push si
          push ax
          push bx
          push dx
          push cx          ;将子程序用到的寄存器入栈      

          mov al,10        
          mul dh
          mov bx,0b800h    
          add ax,bx        
          mov es,ax        ;设置行段地址
          mov bh,0
          mov bl,dl
          add bx,bx
          sub bx,2         ;设置第一个字符的偏移地址(列地址)
       s: mov cl,[si]
          mov ch,0
          jcxz ok          ;如果(cx)=0,转移到标号处;如果不是0,向下执行
          pop cx           ;将子程序中要用的寄存器内的内容出栈
          push cx          ;将子程序要用到的寄存器入栈          
          mov dl,[si]      
          mov es:[bx],dl   ;将字符的ASCII码写入显存
          mov es:[bx+1],cl ;将字符的属性写入显存
          inc si
          add bx,2         ;下一个字符
          jmp near ptr s   ;跳转到s处执行

      ok: pop cx
          pop dx
          pop bx
          pop ax
          pop si           
          pop ds
          pop es           ;将子程序用到的寄存器出栈
          ret

divdw: push bx
       push bp
       mov bp,ax         ;将被除数的低16位存入bp
       mov ax,dx         ;将被除数X得高16位存入ax,作为H的低16位
       mov dx,0          ;将dx置0,作为H的高16位
       div cx            ;H/N
       mov bx,ax         ;将H/N的商存入bx
       mov ax,bp         ;将被除数的低16位存入ax
       div cx            ;[rem(H/N)*65536+L]/N,商(低16位)在ax中
       mov cx,dx         ;将余数存入cx
       mov dx,bx         ;将高16位存入dx
       pop bp
       pop bx
       ret

code ends 
end start       
    没法masm,请问高手问题在哪里?
versaariel
[第3楼] [ 回复时间:2010-04-28 16:10 ] 
荣誉值:62
信誉值:0
注册日期:2009-12-03 13:14
编译器错误就在命令行下方,不要说你看不懂E文=.=
Operand must have size就是masm5.0报的
此问题已结贴!
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved