|
发表于 2018-12-10 00:45:35
|
显示全部楼层
按照你的方法,我试了一下确实会崩溃
但是用g命令直接执行没有问题,所以我怀疑是堆栈太小了(综合中断考虑),堆栈溢出导致改变了返回地址,中断返回到了错误的地址去执行错误的指令
增加栈空间到512字节后,在我这边t命令也没有问题了
- assume cs:code, ds:data;, ds:table, ss:stack
- data segment
- dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
- dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
- data ends
- stack segment
- ; db 16 dup (0)
- db 512 dup (0)
- stack ends
- code segment
- divdw: ;因为10除以ax dx 所得的商大于16位所以在这里我们用了防止溢的这个除法运算方法列如5937000/10就等于90f24大于16位
- push bx ;因为我们下面的程序需要用到bx这个寄存器所以我们bx中的数据先暂时放在栈中
-
- mov cx, 10 ;除数
- push ax ;被除数低位先进站一会在取出,因为我们先要计算高位
- mov ax, dx ;被除数高位先传给ax因为除法的计算方式是div、除数,被除数被储存在了ax和dx中;为什么第二次执行到这一步就崩溃呢?
- mov dx, 0 ;这个公式第一次运算dx先归零,因为我们把32位的数分解到两个寄存器当中去了
- div cx ;一个除法运算
-
- mov bx, ax ;把ax中的数据暂存到bx中
- pop ax ;把站中的上面push bx中的数据取出存入到ax数据中进行下一个div计算
- div cx ;第二个除法运算
-
- mov cx, dx ;把dx中所得到的余数传给cx储存
- mov dx, bx ;把bx中储存的高位商储存给dx,现在低位的商已经传给了ax因为div得到的商是传给ax余数传给dx
- pop bx ;恢复bx中的数据
- ret
-
- year_str: ;该处为year_str标记处 ds = data数据段
- mov ax, word ptr ds:[si]
- add si, 2
- mov dx, word ptr ds:[si]
- add si, 2
- mov bx, 0
- push cx
- year_one:
- call divdw ;除法跳转到divdw处这里是解决除法溢出一个一个除法公式因为被除数里面有32位数
- push cx ;把divdw中传出的余数压进站中
- inc bx ;bx加一这里的bx加一是因为我们下面还需要从占中取出上面计算的余数这个是用来计数的计算我们一共向站中压入多少余数
- mov cx, ax ;ax在divdw中是用于储存低位商的dx储存的是高位商,cx储存的是余数
- jcxz year_three ;如果低位商储存等于零那我们就跳转到year_three标记处
- jmp short year_one ;无条件跳转到year_one标记处
- year_three:
- mov cx, bx ;上面我们用了bx作为计数,记录divdw被执行了几次cx向站中传输了几次数据已被下面输出用
- year_four:
- pop ax ;把站中的divdw所用到的余数取出到ax中
-
-
-
- add ax, '0' ; 把数字变成字符
-
-
-
- mov ah, 2 ;ah中储存的是输出时所拥有的属性2代表着绿色字体
- mov byte ptr es:[bp + di], al ;把al数据输出到0b800h段中该段是显存段每行160个字节
- mov byte ptr es:[bp + di + 1], ah ;这是他的属性
- add di, 2
- loop year_four
-
- mov di, 0
- add bp, 160
- pop cx
- loop year_str
-
-
- ret ; 忘了返回
-
-
-
- start:
- mov ax, data
- mov ds, ax
- mov ax, 0b800h
- mov es, ax
- mov ax, stack
- mov ss, ax
- ; mov sp, 16
- mov sp, 512
- mov cx, 3
- mov di, 0
- mov si, 0
-
-
- xor bp, bp ; 这个忘了清零
-
-
-
- call year_str ;跳转到year_str标记处
-
- mov ax, 4c00h
- int 21h
-
-
- code ends
- end start
复制代码 |
|