鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: 奥普瓯江

[已解决]为什么总是崩溃能这只是一个简单的mov ax, dx

[复制链接]
 楼主| 发表于 2018-12-9 23:44:51 | 显示全部楼层
人造人 发表于 2018-12-9 23:05
我修改过的那两个代码?
弄一个gif(或者其他),把你从编译到运行的过程录下来,我看看

这个就是总是在出错
GIF.gif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-10 00:45:35 | 显示全部楼层
奥普瓯江 发表于 2018-12-9 23:44
这个就是总是在出错

按照你的方法,我试了一下确实会崩溃
但是用g命令直接执行没有问题,所以我怀疑是堆栈太小了(综合中断考虑),堆栈溢出导致改变了返回地址,中断返回到了错误的地址去执行错误的指令

增加栈空间到512字节后,在我这边t命令也没有问题了

  1. assume cs:code, ds:data;, ds:table, ss:stack

  2. data segment
  3.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  4.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  5. data ends   

  6. stack segment
  7.                 ; db 16 dup (0)
  8.                 db 512 dup (0)
  9. stack ends

  10. code segment

  11. divdw:                                      ;因为10除以ax dx 所得的商大于16位所以在这里我们用了防止溢的这个除法运算方法列如5937000/10就等于90f24大于16位               
  12.                 push bx           ;因为我们下面的程序需要用到bx这个寄存器所以我们bx中的数据先暂时放在栈中
  13.                
  14.                 mov cx, 10        ;除数
  15.                 push ax           ;被除数低位先进站一会在取出,因为我们先要计算高位
  16.                 mov ax, dx        ;被除数高位先传给ax因为除法的计算方式是div、除数,被除数被储存在了ax和dx中;为什么第二次执行到这一步就崩溃呢?
  17.                 mov dx, 0         ;这个公式第一次运算dx先归零,因为我们把32位的数分解到两个寄存器当中去了
  18.                 div cx            ;一个除法运算
  19.                
  20.                 mov bx, ax            ;把ax中的数据暂存到bx中
  21.                 pop ax            ;把站中的上面push bx中的数据取出存入到ax数据中进行下一个div计算
  22.                 div cx            ;第二个除法运算
  23.                
  24.                 mov cx, dx        ;把dx中所得到的余数传给cx储存
  25.                 mov dx, bx        ;把bx中储存的高位商储存给dx,现在低位的商已经传给了ax因为div得到的商是传给ax余数传给dx
  26.                 pop bx                      ;恢复bx中的数据
  27.                 ret
  28.                
  29. year_str:                                                        ;该处为year_str标记处  ds = data数据段
  30.                 mov ax, word ptr ds:[si]
  31.                 add si, 2
  32.                 mov dx, word ptr ds:[si]
  33.                 add si, 2
  34.                 mov bx, 0
  35.                 push cx
  36. year_one:
  37.                 call divdw                                    ;除法跳转到divdw处这里是解决除法溢出一个一个除法公式因为被除数里面有32位数
  38.                 push cx                     ;把divdw中传出的余数压进站中
  39.                 inc bx                                                ;bx加一这里的bx加一是因为我们下面还需要从占中取出上面计算的余数这个是用来计数的计算我们一共向站中压入多少余数
  40.                 mov cx, ax                                        ;ax在divdw中是用于储存低位商的dx储存的是高位商,cx储存的是余数
  41.                 jcxz year_three             ;如果低位商储存等于零那我们就跳转到year_three标记处
  42.                 jmp short year_one                        ;无条件跳转到year_one标记处
  43. year_three:
  44.                 mov cx, bx                  ;上面我们用了bx作为计数,记录divdw被执行了几次cx向站中传输了几次数据已被下面输出用
  45. year_four:
  46.                 pop ax                      ;把站中的divdw所用到的余数取出到ax中
  47.                
  48.                
  49.                
  50.                 add        ax, '0'                ; 把数字变成字符
  51.                
  52.                
  53.                
  54.                 mov ah, 2                   ;ah中储存的是输出时所拥有的属性2代表着绿色字体
  55.                 mov byte ptr es:[bp + di], al  ;把al数据输出到0b800h段中该段是显存段每行160个字节
  56.                 mov byte ptr es:[bp + di + 1], ah  ;这是他的属性
  57.                 add di, 2                          
  58.                 loop year_four
  59.                
  60.                 mov di, 0
  61.                 add bp, 160
  62.                 pop cx
  63.                 loop year_str
  64.                
  65.                
  66.                 ret                ; 忘了返回
  67.                
  68.                
  69.                
  70. start:        
  71.                 mov ax, data
  72.                 mov ds, ax
  73.                 mov ax, 0b800h
  74.                 mov es, ax
  75.                 mov ax, stack
  76.                 mov ss, ax
  77.                 ; mov sp, 16
  78.                 mov sp, 512
  79.                 mov cx, 3
  80.                 mov di, 0
  81.                 mov si, 0
  82.                
  83.                
  84.                 xor        bp, bp        ; 这个忘了清零
  85.                
  86.                
  87.                
  88.                 call year_str    ;跳转到year_str标记处
  89.                

  90.                 mov ax, 4c00h
  91.                 int 21h
  92.         
  93.                
  94. code ends
  95. end start
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-10 02:02:06 | 显示全部楼层
人造人 发表于 2018-12-10 00:45
按照你的方法,我试了一下确实会崩溃
但是用g命令直接执行没有问题,所以我怀疑是堆栈太小了(综合中断 ...

谢谢我把那个栈改大了但是还是出现这种问题用不了t向下执行但是可以用G向下执行,现在我知道我这个程序逻辑正确了就行,别的问题因为接触汇编的时间还短慢慢向下学吧,希望以后能解答,再次说声谢谢这么晚还帮我回答我替,十分感谢,麻烦了,下面是gif
这个是用G执行的是可以执行出来数字
3.gif
但是这个用t执行的确不行不知道为什么先这样吧,谢谢您了,谢谢您的帮助
2.gif
  1. assume cs:code, ds:data;, ds:table, ss:stack

  2. data segment
  3.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  4.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  5. data ends   

  6. stack segment
  7.                 db 512 dup (0)
  8. stack ends

  9. code segment

  10. divdw:                                      ;因为10除以ax dx 所得的商大于16位所以在这里我们用了防止溢的这个除法运算方法列如5937000/10就等于90f24大于16位               
  11.                 push bx           ;因为我们下面的程序需要用到bx这个寄存器所以我们bx中的数据先暂时放在栈中
  12.                
  13.                 mov cx, 10        ;除数
  14.                 push ax           ;被除数低位先进站一会在取出,因为我们先要计算高位
  15.                 mov ax, dx        ;被除数高位先传给ax因为除法的计算方式是div、除数,被除数被储存在了ax和dx中;为什么第二次执行到这一步就崩溃呢?
  16.                 mov dx, 0         ;这个公式第一次运算dx先归零,因为我们把32位的数分解到两个寄存器当中去了
  17.                 div cx            ;一个除法运算
  18.                
  19.                 mov bx, ax            ;把ax中的数据暂存到bx中
  20.                 pop ax            ;把站中的上面push bx中的数据取出存入到ax数据中进行下一个div计算
  21.                 div cx            ;第二个除法运算
  22.                 mov cx, dx        ;把dx中所得到的余数传给cx储存
  23.                 mov dx, bx        ;把bx中储存的高位商储存给dx,现在低位的商已经传给了ax因为div得到的商是传给ax余数传给dx
  24.                 pop bx                      ;恢复bx中的数据
  25.                 ret
  26.                
  27. year_str:                                                        ;该处为year_str标记处  ds = data数据段
  28.                 mov ax, word ptr ds:[si]
  29.                 add si, 2
  30.                 mov dx, word ptr ds:[si]
  31.                 add si, 2
  32.                 mov bx, 0
  33.                 push cx
  34. year_one:
  35.                 call divdw                                 ;除法跳转到divdw处这里是解决除法溢出一个一个除法公式因为被除数里面有32位数
  36.                 add cx, '0'
  37.                 push cx                     ;把divdw中传出的余数压进站中
  38.                 inc bx                                                ;bx加一这里的bx加一是因为我们下面还需要从占中取出上面计算的余数这个是用来计数的计算我们一共向站中压入多少余数
  39.                 mov cx, ax                                        ;ax在divdw中是用于储存低位商的dx储存的是高位商,cx储存的是余数
  40.                 jcxz year_three             ;如果低位商储存等于零那我们就跳转到year_three标记处
  41.                 jmp short year_one                        ;无条件跳转到year_one标记处
  42. year_three:
  43.                 mov cx, bx                  ;上面我们用了bx作为计数,记录divdw被执行了几次cx向站中传输了几次数据已被下面输出用
  44. year_four:
  45.                 pop ax                      ;把站中的divdw所用到的余数取出到ax中
  46.                 mov ah, 2                   ;ah中储存的是输出时所拥有的属性2代表着绿色字体
  47.                 mov byte ptr es:[bp + di], al  ;把al数据输出到0b800h段中该段是显存段每行160个字节
  48.                 mov byte ptr es:[bp + di + 1], ah  ;这是他的属性
  49.                 add di, 2                          
  50.                 loop year_four
  51.                
  52.                 mov di, 0
  53.                 add bp, 160
  54.                 pop cx
  55.                 loop year_str
  56.                 ret
  57. start:       
  58.                 mov ax, data
  59.                 mov ds, ax
  60.                 mov ax, 0b800h
  61.                 mov es, ax
  62.                 mov ax, stack
  63.                 mov ss, ax
  64.                 mov sp, 16
  65.                 mov cx, 21
  66.                 mov bp, 480
  67.                 mov di, 0
  68.                 mov si, 0
  69.                 call year_str    ;跳转到year_str标记处
  70.                

  71.                 mov ax, 4c00h
  72.                 int 21h
  73.        
  74.                
  75. code ends
  76. end start
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-10 11:22:22 | 显示全部楼层
本帖最后由 tianyuan 于 2018-12-10 11:42 编辑

我用人造人改后的代码没问题 单步跟综-t没有崩溃,难道是环境的原因   我用DOSBox
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-10 12:17:43 From FishC Mobile | 显示全部楼层
assume伪指令把栈给注释掉了,看看你link时有没有出现 waering L4021: no stack segment
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-10 12:37:12 | 显示全部楼层
看,我发现了什么!

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-10 13:34:59 From FishC Mobile | 显示全部楼层
本帖最后由 tianyuan 于 2018-12-10 13:37 编辑
人造人 发表于 2018-12-10 12:37
看,我发现了什么!


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-10 14:38:19 | 显示全部楼层
人造人 发表于 2018-12-10 12:37
看,我发现了什么!

哎就是他的问题,是我错了改过来就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 23:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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