鱼C论坛

 找回密码
 立即注册
查看: 3567|回复: 3

求大神指点实验7

[复制链接]
发表于 2019-2-15 21:50:55 | 显示全部楼层 |阅读模式

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

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

x
我只尝试了表格的四行输入,计算人均输入的时候计算了三个,计算第四个的时候dosbox死机了。求指点。
看起来不像除法溢出,因为1356/13=104=68H,不会超过一个寄存器AX,AX可以放两个字节。也没有除数为0的情况。
assume cs:codesg, ds:datasg, ss:stacksg
datasg segment
  db '1975','1976','1977','1978'
  dd 16,22,382,1356
  dw 3,7,9,13
datasg ends
stacksg segment
  dw 0,0,0,0,0,0,0,0
stacksg ends
table segment
  db 4 dup('year summ ne ?? ')
table ends
codesg segment
start: mov ax,datasg
       mov ds,ax
       mov ax,stacksg
       mov ss,ax
       mov sp,16
       mov ax,table
       mov es,ax
      
       ;读入年份,bx表示哪一列的偏址,si表示数据段的偏址,di表示目标表格里行造成的偏址

       mov bx,0
       mov si,0
       mov cx,4
    s0:mov ax,si
       mov di,4
       mul di
       mov di,ax
       mov al, ds:[bx+si+0]
       mov es:[bx+di+0],al
       mov al, ds:[bx+si+1]
       mov es:[bx+di+1],al
       mov al, ds:[bx+si+2]
       mov es:[bx+di+2],al
       mov al, ds:[bx+si+3]
       mov es:[bx+di+3],al
       mov al,20h
       mov es:[bx+di+4],al
       add si,4
       loop s0
      
       ;读入收入
       add bx,5
       mov si,0
       mov cx,4


    s1:mov ax,si
       mov di,4
       div di
       mov di,10H
       mul di
       mov di,ax
       mov ax, ds:[si+16]
       mov es:[bx+di+0], ax
       mov dx, ds:[si+18]
       mov es:[bx+di+2], dx
       add si, 4
       loop s1
   
       ;读入雇员数
       add bx,5
       mov si,0
       mov cx,4

    s2:mov ax,si
       mov di, 2
       div di
       mov di,10H
       mul di
       mov di,ax
       mov ax, ds:[si+32]
       mov es:[bx+di+0], ax
       add si, 2
       loop s2
      
       ;计算人均收入=收入/雇员数
       add bx,3
       mov si,0
       mov bp,0       
       mov cx,4

    s3:mov ax,si
       mov di, 4
       div di
       mov di,10H
       mul di
       mov di,ax
       mov ax, ds:[si+16]
       mov dx, ds:[si+18]
       div word ptr ds:[bp+32]       
       mov es:[bx+di+0], ax
       add si, 4
       add bp,2
       loop s3

       mov ax,4c00h
       int 21h
codesg ends
end start

运行结果
QQ截图20190215213239.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-2-15 23:35:09 | 显示全部楼层
本帖最后由 jackz007 于 2019-2-16 11:44 编辑

      做除法的时候,由于 dx 不为 0 导致溢出,只要略加修改便可解决问题:

     
  1. assume cs:codesg, ds:datasg, ss:stacksg
  2. datasg segment
  3.     db '1975' , '1976' , '1977' , '1978'
  4.     dd     16 ,     22 ,    382 ,   1356
  5.     dw      3 ,      7 ,      9 ,     13
  6. datasg ends
  7. stacksg segment
  8.     dw 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
  9. stacksg ends
  10. table segment
  11.     db 4 dup('year summ ne ?? ')
  12. table ends
  13. codesg segment
  14. start: mov ax , datasg
  15.        mov ds , ax
  16.        mov ax , stacksg
  17.        mov ss , ax
  18.        mov sp , 16
  19.        mov ax , table
  20.        mov es , ax
  21.        ; 读入年份,bx 表示哪一列的偏址,si表示数据段的偏址,di表示目标表格里行造成的偏址
  22.        mov bx , 0
  23.        mov si , 0
  24.        mov cx , 4
  25.     s0:mov ax , si
  26.        mov di , 4
  27.        mul di
  28.        mov di , ax
  29.        mov al , ds:[bx+si+0]
  30.        mov es:[bx+di+0] , al
  31.        mov al , ds:[bx+si+1]
  32.        mov es:[bx+di+1] , al
  33.        mov al , ds:[bx+si+2]
  34.        mov es:[bx+di+2] , al
  35.        mov al , ds:[bx+si+3]
  36.        mov es:[bx+di+3] , al
  37.        mov al , 20h
  38.        mov es:[bx+di+4] , al
  39.        add si , 4
  40.        loop s0
  41.        ; 读入收入
  42.        add bx , 5
  43.        mov si , 0
  44.        mov cx , 4
  45.     s1:mov ax , si
  46.        cwd                      ; 新增此句,防止做除法时 dx 不为零
  47.        mov di , 4
  48.        div di
  49.        mov di , 10H
  50.        mul di
  51.        mov di , ax
  52.        mov ax , ds:[si+16]
  53.        mov es:[bx+di+0] , ax
  54.        mov dx , ds:[si+18]
  55.        mov es:[bx+di+2] , dx
  56.        add si , 4
  57.        loop s1
  58.        ; 读入雇员数
  59.        add bx , 5
  60.        mov si , 0
  61.        mov cx , 4
  62.     s2:mov ax , si
  63.        cwd                      ; 新增此句,防止做除法时 dx 不为零
  64.        mov di , 2
  65.        div di
  66.        mov di , 10H
  67.        mul di
  68.        mov di , ax
  69.        mov ax , ds:[si+32]
  70.        mov es:[bx+di+0] , ax
  71.        add si , 2
  72.        loop s2
  73.        ; 计算人均收入 = 收入 / 雇员数
  74.        add bx , 3
  75.        mov si , 0
  76.        mov bp , 0        
  77.        mov cx , 4
  78.     s3:mov ax , si
  79.        cwd                      ; 新增此句,防止做除法时 dx 不为零
  80.        mov di , 4
  81.        div di                   ; 除法溢出发生点,原因,做除法时 dx 不为零
  82.        mov di , 10H
  83.        mul di
  84.        mov di , ax
  85.        mov ax , ds:[si+16]
  86.        mov dx , ds:[si+18]
  87.        div word ptr ds:[bp+32]  ; 16 位除法,ax 保存商,dx 保存余数,如果不能整除,即埋下后续 div 运算溢出隐患      
  88.        mov es:[bx+di+0] , ax
  89.        add si , 4
  90.        add bp , 2
  91.        loop s3
  92.        mov ax , 4c00h
  93.        int 21h
  94. codesg ends
  95. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-16 09:56:17 | 显示全部楼层
jackz007 发表于 2019-2-15 23:35
做除法的时候,由于 dx 不为 0 导致溢出,只要略加修改便可解决问题:

还是会溢出。
为什么dx不为0会导致溢出呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-16 10:59:09 | 显示全部楼层
本帖最后由 jackz007 于 2019-2-17 00:47 编辑
peppapig 发表于 2019-2-16 09:56
还是会溢出。
为什么dx不为0会导致溢出呢?


        因为 16 位除法中,被除数是  dx : ax,运算结果 ax 保存商,dx 保存余数,如果运算结果商的值太大,超出 16 位,ax 无法保存,势必会产生溢出。被除数是 32 位,而除数只有 16 位,这种情况很容易产生。

        为了证明这一点,可以在 debug 中输入以下代码然后进行调试得到验证:

  1. mov dx , 2
  2. xor ax , ax
  3. push dx
  4. pop cx
  5. div cx
  6. int3
复制代码


        以上代码实际上是计算

        20000h / 2h

        计算结果,商 = 10000h,由于 ax 无法存储此值,所以导致溢出错误,所谓 dx 不为 0 导致溢出,说的正是这种情况 。

        楼主在代码中一共有 4 处使用了 16 位除法,除了最后那 1 处,前面的 3 处都没有专门为 dx 寄存器赋过值。也未对 dx 寄存器进行任何的处理,这是很严重的问题,因为不论你是否意识到, 寄存器 dx 注定是要参与运算的!

        所以,在做 16 位除法运算时,如果没有专门用到 dx 寄存器,必须事先用下面的指令之一来处理 dx 寄存器:

  1. cwd          ;  把寄存器 ax 的值扩展到 dx 成为 32 位数

  2. xor dx , dx  ;  把 dx 寄存器清零
复制代码


        只有这样做,才能保证计算结果的正确。

        所以,我修改的代码不可能还有溢出错误,楼主一定要认真查一查。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 08:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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