鱼C论坛

 找回密码
 立即注册
查看: 785|回复: 4

[已解决]div

[复制链接]
发表于 2023-8-13 15:28:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x


  1. ;名称:dtoc
  2. ;功能:将word型数据转变为表示十进制数的字符串, 字符串以0为结尾符
  3. ;参数:(a x) =word型数据
  4. ;ds:si指向字符串的首地址
  5. ;返回值:无

  6. ;应用举例:编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。
  7. ;在显示时我们调用本次实验中的第一个子程序show_str。


  8. assume cs:code

  9. data segment
  10.         db 10 dup(0)

  11. data ends

  12.   
  13. code segment
  14.       start:
  15.                 mov ax,12666
  16.                         mov bx,data
  17.                         mov ds,bx
  18.                         mov si,0
  19.                         call dtoc
  20.                         mov dh,8
  21.                         mov dl,3
  22.                         mov cl,2
  23.                         call show_str
  24.                        
  25.                         mov ax,4c00h
  26.                         int 21h
  27.           
  28.           
  29.           dtoc:push bx
  30.                push dx
  31.                    push cx
  32.                   
  33.                    ;计算字符总数
  34.                    mov bx,1  ;bx保存字符总数
  35.                    mov dl,10
  36.                    push ax  ;保存被除数
  37.             s2:div dl
  38.                    mov ch,0
  39.                    mov cl,al ;把商传给cx
  40.                    jcxz ss1
  41.                    inc bx   ;字符数加1
  42.                    mov ah,0  ;清除余数,ax就是商
  43.                   
  44.                    mov cx,2  ;保证loop时,cx不等于0
  45.                    loop s2
  46.                                
  47.                 ss1:pop ax  ;读取被除数
  48.                
  49.                 ;写入字符
  50.                 ;bx=字符总数,bx-1就是偏移量
  51.                
  52.                    mov bx,0   ;写结束字符0
  53.                   
  54.                 s3:div dl
  55.                    add ah,30h   ;把余数转换成ASCII吗
  56.                    mov [bx-1],ah  ;写入字符,注意倒序
  57.            mov ah,0  ;清除余数,ax就是商
  58.            mov ch,0
  59.                    mov cl,al ;把商传给cx
  60.            jcxz s4  ;如果商=0就结束   
  61.                    dec bx
  62.                    mov cx,2  ;保证loop时,cx不等于0
  63.                    loop s3               
  64.                                                           
  65.                 s4:        mov si,0  ;字符串首地址               
  66.                     pop cx
  67.                         pop dx
  68.                         pop bx
  69.                         ret
  70.                        
  71.                        
  72.                        
  73.                        
  74.   show_str:  ;子程序用到的寄存器一定要先保存
  75.            push ax
  76.            push es
  77.                    push bx
  78.                    push bp
  79.                   
  80.                   
  81.            
  82.                    mov ax,0B800h   ;显存段地址
  83.                    mov es,ax
  84.                    mov bl,cl       ;bl保存颜色
  85.                                      
  86.                    ;计算偏移量
  87.                    mov al,160
  88.                    mul dh
  89.                    mov bp,ax
  90.                    mov al,2
  91.                    mul dl
  92.                    add bp,ax  ;计算出偏移量;bp显存偏移量
  93.                                                  
  94.                  s:mov ch,0
  95.                    mov cl,[si]  ; 提取字符
  96.                    jcxz s1     ;0字符返回
  97.                    mov es:[bp],cl
  98.                    mov es:[bp+1],bl
  99.                    inc si
  100.                    add bp,2
  101.                    jmp s
  102.                              
  103.   
  104.   
  105.                 s1:pop bp
  106.                    pop bx
  107.                    pop es
  108.                    pop ax
  109.            ret      ;返回
  110.           
  111. code ends
  112. end start


复制代码



我的问题:
调试执行时 发现执行div dl  之后,出现错误,如图


最佳答案
2023-8-13 15:29:27
根据代码分析,执行  div dl  之前, dx  寄存器的值应该是被除数  ax  的高16位,而被除数  ax  的低16位应该是  al  寄存器的值。在这段代码中, ax  寄存器的值是  12666 ,所以  dx  的值应该是  0 , ax  的值应该是  12666 。但是在执行  div dl  之前,代码没有将  ax  的值保存到  dx  寄存器中,导致  dx  的值不正确,从而引发错误。

为了解决这个问题,可以在执行  div dl  之前,添加一条指令  mov dx, ax ,将  ax  寄存器的值保存到  dx  寄存器中。这样就可以确保  dx  的值正确,从而避免错误的发生。

修改后的代码如下:

  1. dtoc:
  2.     push bx
  3.     push dx
  4.     push cx
  5.    
  6.     ; 计算字符总数
  7.     mov bx, 1 ; bx 保存字符总数
  8.     mov dl, 10
  9.     push ax ; 保存被除数
  10. s2:
  11.     mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
  12.     div dl
  13.     mov ch, 0
  14.     mov cl, al ; 把商传给 cx
  15.     jcxz ss1
  16.     inc bx ; 字符数加1
  17.     mov ah, 0 ; 清除余数,ax 就是商
  18.    
  19.     mov cx, 2 ; 保证 loop 时,cx 不等于 0
  20.     loop s2
  21.    
  22. ss1:
  23.     pop ax ; 读取被除数
  24.    
  25.     ; 写入字符
  26.     ; bx = 字符总数,bx - 1 就是偏移量
  27.    
  28.     mov bx, 0 ; 写结束字符 0
  29.    
  30. s3:
  31.     mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
  32.     div dl
  33.     add ah, 30h ; 把余数转换成 ASCII 码
  34.     mov [bx-1], ah ; 写入字符,注意倒序
  35.    
  36.     mov ah, 0 ; 清除余数,ax 就是商
  37.     mov ch, 0
  38.     mov cl, al ; 把商传给 cx
  39.     jcxz s4 ; 如果商 = 0 就结束
  40.     dec bx
  41.     mov cx, 2 ; 保证 loop 时,cx 不等于 0
  42.     loop s3
  43.    
  44. s4:
  45.     mov si, 0 ; 字符串首地址
  46.    
  47.     pop cx
  48.     pop dx
  49.     pop bx
  50.     ret
复制代码


修改后的代码中,添加了  mov dx, ax  指令,将  ax  寄存器的值保存到  dx  寄存器中,确保了  dx  的值正确。这样就可以正常执行  div dl  指令了。
1111.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-8-13 15:29:20 | 显示全部楼层
根据您提供的信息和代码,问题出现在执行 div dl 指令之后。错误可能是由于除数 dl 的值为 0 导致的。在您的代码中,为了进行除法操作,您需要先将除数放入 dl 寄存器中。

在您的代码中,我没有看到为 dl 寄存器赋值的指令。请确保在执行 div dl 之前,将正确的除数值加载到 dl 寄存器中。

例如,在您的示例中,您可以在 dtoc 子程序中添加以下指令来加载除数值:

  1. mov dl, 10
复制代码


请尝试添加这一指令,并重新运行程序。如果问题仍然存在,请提供更多相关的信息或完整的代码,以便我能够更好地帮助您解决问题。
如果问题已经解决,请设置最佳答案
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-13 15:29:27 | 显示全部楼层    本楼为最佳答案   
根据代码分析,执行  div dl  之前, dx  寄存器的值应该是被除数  ax  的高16位,而被除数  ax  的低16位应该是  al  寄存器的值。在这段代码中, ax  寄存器的值是  12666 ,所以  dx  的值应该是  0 , ax  的值应该是  12666 。但是在执行  div dl  之前,代码没有将  ax  的值保存到  dx  寄存器中,导致  dx  的值不正确,从而引发错误。

为了解决这个问题,可以在执行  div dl  之前,添加一条指令  mov dx, ax ,将  ax  寄存器的值保存到  dx  寄存器中。这样就可以确保  dx  的值正确,从而避免错误的发生。

修改后的代码如下:

  1. dtoc:
  2.     push bx
  3.     push dx
  4.     push cx
  5.    
  6.     ; 计算字符总数
  7.     mov bx, 1 ; bx 保存字符总数
  8.     mov dl, 10
  9.     push ax ; 保存被除数
  10. s2:
  11.     mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
  12.     div dl
  13.     mov ch, 0
  14.     mov cl, al ; 把商传给 cx
  15.     jcxz ss1
  16.     inc bx ; 字符数加1
  17.     mov ah, 0 ; 清除余数,ax 就是商
  18.    
  19.     mov cx, 2 ; 保证 loop 时,cx 不等于 0
  20.     loop s2
  21.    
  22. ss1:
  23.     pop ax ; 读取被除数
  24.    
  25.     ; 写入字符
  26.     ; bx = 字符总数,bx - 1 就是偏移量
  27.    
  28.     mov bx, 0 ; 写结束字符 0
  29.    
  30. s3:
  31.     mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
  32.     div dl
  33.     add ah, 30h ; 把余数转换成 ASCII 码
  34.     mov [bx-1], ah ; 写入字符,注意倒序
  35.    
  36.     mov ah, 0 ; 清除余数,ax 就是商
  37.     mov ch, 0
  38.     mov cl, al ; 把商传给 cx
  39.     jcxz s4 ; 如果商 = 0 就结束
  40.     dec bx
  41.     mov cx, 2 ; 保证 loop 时,cx 不等于 0
  42.     loop s3
  43.    
  44. s4:
  45.     mov si, 0 ; 字符串首地址
  46.    
  47.     pop cx
  48.     pop dx
  49.     pop bx
  50.     ret
复制代码


修改后的代码中,添加了  mov dx, ax  指令,将  ax  寄存器的值保存到  dx  寄存器中,确保了  dx  的值正确。这样就可以正常执行  div dl  指令了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-13 15:31:07 | 显示全部楼层
陶远航 发表于 2023-8-13 15:29
根据您提供的信息和代码,问题出现在执行 div dl 指令之后。错误可能是由于除数 dl 的值为 0 导致的。在您 ...

就上面隔一行 就是你写的指令
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-13 15:33:25 | 显示全部楼层
isdkz 发表于 2023-8-13 15:29
根据代码分析,执行  div dl  之前, dx  寄存器的值应该是被除数  ax  的高16位,而被除数  ax  的低16位 ...

除数是8位,被除数是16位    此时al保存商  ah保存余数   不会修改DX值的   ??
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-19 22:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表