lm68140318 发表于 2023-8-13 15:28:48

div



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

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


assume cs:code

data segment
        db 10 dup(0)

data 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 bx
             push dx
                   push cx
                  
                   ;计算字符总数
                   mov bx,1;bx保存字符总数
                   mov dl,10
                   push ax;保存被除数
          s2:div dl
                   mov ch,0
                   mov cl,al ;把商传给cx
                   jcxz ss1
                   inc bx   ;字符数加1
                   mov ah,0;清除余数,ax就是商
                  
                   mov cx,2;保证loop时,cx不等于0
                   loop s2
                               
                ss1:pop ax;读取被除数
               
                ;写入字符
                ;bx=字符总数,bx-1就是偏移量
               
                   mov bx,0   ;写结束字符0
                  
                s3:div dl
                   add ah,30h   ;把余数转换成ASCII吗
                   mov ,ah;写入字符,注意倒序
         mov ah,0;清除余数,ax就是商
         mov ch,0
                   mov cl,al ;把商传给cx
         jcxz s4;如果商=0就结束   
                   dec bx
                   mov cx,2;保证loop时,cx不等于0
                   loop s3               
                                                          
                s4:        mov si,0;字符串首地址               
                  pop cx
                        pop dx
                        pop bx
                        ret
                       
                       
                       
                       
show_str:;子程序用到的寄存器一定要先保存
         push ax
         push es
                   push bx
                   push bp
                  
                  
         
                   mov ax,0B800h   ;显存段地址
                   mov es,ax
                   mov bl,cl       ;bl保存颜色
                                     
                   ;计算偏移量
                   mov al,160
                   mul dh
                   mov bp,ax
                   mov al,2
                   mul dl
                   add bp,ax;计算出偏移量;bp显存偏移量
                                               
               s:mov ch,0
                   mov cl,; 提取字符
                   jcxz s1   ;0字符返回
                   mov es:,cl
                   mov es:,bl
                   inc si
                   add bp,2
                   jmp s
                             


                s1:pop bp
                   pop bx
                   pop es
                   pop ax
         ret      ;返回
          
code ends
end start





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


陶远航 发表于 2023-8-13 15:29:20

根据您提供的信息和代码,问题出现在执行 div dl 指令之后。错误可能是由于除数 dl 的值为 0 导致的。在您的代码中,为了进行除法操作,您需要先将除数放入 dl 寄存器中。

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

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

mov dl, 10


请尝试添加这一指令,并重新运行程序。如果问题仍然存在,请提供更多相关的信息或完整的代码,以便我能够更好地帮助您解决问题。
如果问题已经解决,请设置最佳答案

isdkz 发表于 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的值正确,从而避免错误的发生。

修改后的代码如下:

dtoc:
    push bx
    push dx
    push cx
   
    ; 计算字符总数
    mov bx, 1 ; bx 保存字符总数
    mov dl, 10
    push ax ; 保存被除数
s2:
    mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
    div dl
    mov ch, 0
    mov cl, al ; 把商传给 cx
    jcxz ss1
    inc bx ; 字符数加1
    mov ah, 0 ; 清除余数,ax 就是商
   
    mov cx, 2 ; 保证 loop 时,cx 不等于 0
    loop s2
   
ss1:
    pop ax ; 读取被除数
   
    ; 写入字符
    ; bx = 字符总数,bx - 1 就是偏移量
   
    mov bx, 0 ; 写结束字符 0
   
s3:
    mov dx, ax ; 将 ax 的值保存到 dx 寄存器中
    div dl
    add ah, 30h ; 把余数转换成 ASCII 码
    mov , ah ; 写入字符,注意倒序
   
    mov ah, 0 ; 清除余数,ax 就是商
    mov ch, 0
    mov cl, al ; 把商传给 cx
    jcxz s4 ; 如果商 = 0 就结束
    dec bx
    mov cx, 2 ; 保证 loop 时,cx 不等于 0
    loop s3
   
s4:
    mov si, 0 ; 字符串首地址
   
    pop cx
    pop dx
    pop bx
    ret


修改后的代码中,添加了mov dx, ax指令,将ax寄存器的值保存到dx寄存器中,确保了dx的值正确。这样就可以正常执行div dl指令了。

lm68140318 发表于 2023-8-13 15:31:07

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

就上面隔一行 就是你写的指令

lm68140318 发表于 2023-8-13 15:33:25

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

除数是8位,被除数是16位    此时al保存商ah保存余数   不会修改DX值的   ??
页: [1]
查看完整版本: div