奥普瓯江 发表于 2018-12-8 11:39:27

为什么总是崩溃能这只是一个简单的mov ax, dx

为什么总是崩溃呢?哪位大神能帮忙找找原因呢?谢谢
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)
stack ends

code segment

divdw:
                ;push bx
               
                ;mov cx, 10
                push ax
                mov ax, dx      ;为什么第二次执行到这一步就崩溃呢?
                mov dx, 0
                div cx
               
                mov bx, ax
                pop ax
                div cx
               
                mov cx, dx
                mov dx, bx
                ;pop bx
                ret
year_str:
                mov ax, word ptr ds:
                add si, 2
                mov dx, word ptr ds:
                add si, 2
                mov bx, 0
                push cx
year_one:
                mov cx, 10
                push bx
                call divdw
                pop bx
                push cx
                inc bx
                mov cx, ax
                jcxz year_three
                jmp short year_one
year_three:
                mov cx, bx
year_four:
                pop ax
                mov ah, 2
                mov byte ptr es:, al
                mov byte ptr es:, ah
                add di, 2
                loop year_four
               
                mov di, 0
                add bp, 160
                pop cx
                loop year_str
start:       
                mov ax, data
                mov ds, ax
                mov ax, 0b800h
                mov es, ax
                mov ax, stack
                mov ss, ax
                mov sp, 16
                mov cx, 3
                mov di, 0
                mov si, 0
                call year_str
               

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

人造人 发表于 2018-12-8 12:18:06

写好注释,每一个子程序的入口参数以及出口参数,还有这个程序需要完成什么功能,它来自哪里

TCY 发表于 2018-12-8 13:35:46

错误原因

翼是孤独 发表于 2018-12-8 16:24:38

你的程序有终止条件吗,程序不可能一直运行啊

奥普瓯江 发表于 2018-12-8 17:01:44

人造人 发表于 2018-12-8 12:18
写好注释,每一个子程序的入口参数以及出口参数,还有这个程序需要完成什么功能,它来自哪里

我想把数据段(data)中的32位数据竖着投射到屏幕上(0b800段中),但是每到19段的时候他就出现错误提示不向下执行了。我这找了半天原因也不知道为什么还望帮忙解答一下,下面的是我做的标注不知道能不能理解,不是很熟悉汇编,算是想到哪里写到哪里还麻烦你费劲理解一下,这个东西太乱了太难学了
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)
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:
                add si, 2
                mov dx, word ptr ds:
                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中
                mov ah, 2                   ;ah中储存的是输出时所拥有的属性2代表着绿色字体
                mov byte ptr es:, al;把al数据输出到0b800h段中该段是显存段每行160个字节
                mov byte ptr es:, ah;这是他的属性
                add di, 2                        
                loop year_four
               
                mov di, 0
                add bp, 160
                pop cx
                loop year_str
start:       
                mov ax, data
                mov ds, ax
                mov ax, 0b800h
                mov es, ax
                mov ax, stack
                mov ss, ax
                mov sp, 16
                mov cx, 3
                mov di, 0
                mov si, 0
                call year_str    ;跳转到year_str标记处
               

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

奥普瓯江 发表于 2018-12-8 17:11:47

翼是孤独 发表于 2018-12-8 16:24
你的程序有终止条件吗,程序不可能一直运行啊

有终止条件我用的是loop 当cx中的数据是1的时候就是终止的时候cx我占时存入了站中在跳转到year_str是有一个push cx这个就是我存入的,在这个题中我占时cx初始值设定成了 3让他做三次循环

奥普瓯江 发表于 2018-12-8 18:37:59

{:10_254:}来个人给解答一下谢谢了,别沉自己顶一下

人造人 发表于 2018-12-9 15:28:38

奥普瓯江 发表于 2018-12-8 18:37
来个人给解答一下谢谢了,别沉自己顶一下

写好注释,每一个子程序的入口参数以及出口参数,还有这个程序需要完成什么功能,它来自哪里

这个程序是哪来的?

奥普瓯江 发表于 2018-12-9 15:56:01

人造人 发表于 2018-12-9 15:28
写好注释,每一个子程序的入口参数以及出口参数,还有这个程序需要完成什么功能,它来自哪里

这个程序 ...

王爽汇编语言第二版,课程设计1,我是从里面分解出来的他让把实验7中的power idea公司的数据按照图10.2所示的格式在屏幕上显示我日期显示那个我写出来了,(日期那个是显示四位数字),但是这个显示大于16位65535个数位的时候用除法divdw连续加载就会出现错误比如说这个数字5937000

奥普瓯江 发表于 2018-12-9 16:00:44

人造人 发表于 2018-12-9 15:28
写好注释,每一个子程序的入口参数以及出口参数,还有这个程序需要完成什么功能,它来自哪里

这个程序 ...

我吧这个程序在分解一下并写了注释,但是还是会出现问题,跟上面那个问题一样,这回只处理一次处理的数据是地21个数据5937000,你看看我这是哪里错了呢?麻烦了
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)
stack ends

code segment
start:
                mov ax, data          ;设定数据段data
                mov ds, ax
                mov ax, stack         ;设定栈段
                mov ss, ax
                mov sp, 16
                mov bx, 0
                mov ax, word ptr ds:;把地21组数5937000转换成16位5a9768低位传给ax,9768
                mov dx, word ptr ds:;把地21组数5937000转换成16位5a9768高位传给dx,005a
div_one:
                push bx                   ;bx作为计数,记录divdw一共运行了几次   
                call divdw                                   ;跳转到divdw标记处进行32位商的除法运算
                pop bx                                          ;因为divdw里面得使bx这个寄存器,所以我就占时把他放入了栈中,此处是进行了取回
                inc bx                  ;bx作为计数器加一
                push cx                   ;把cx推入栈中占时储存
                mov cx, ax                ;把ax商的传给cx因为jcxz需要用到
                jcxz div_two                          ;jcxz如果cx内部储存的数据为0那么久这行该程序跳转到div_two处
                jmp short div_one                  ;无条件跳转到div_one标记处
div_two:
                mov ax, 4c00h                          ;结束
                int 21h
divdw:                                                          ;跳转到该标记处后,ax中储存的是低位数dx中储存的是高位数
                mov cx, 10                                  ;除数设定在cx中,在本程序中是10
                push ax                                          ;先暂时把ax中的数据储存起来先进行高位运算
                mov ax, dx                                  ;先把dx中的数据传给ax使得他在下面进行除法运算
                mov dx, 0               ;先把dx归零因为一开始dx中如果有数据就会影响除法的精度
                div cx                  ;除法运算,被除数放在ax中,除数放在cx中
               
                mov bx, ax                ;商放放在了ax中,dx中存放余数,这里余数先不要去管他下面第二个除法还需要要用到
               
                pop ax                  ;取出低位的被除数到ax中以供下面进行除法运算
                div cx                                          ;除法运算被除数分别在dx和ax中,dx中的数据是上一个除数遗留下来的余数在此处充当被除数高位低位是在站中取出的那个数据
                                                                  ;下面除数的商分别储存在ax中余数储存在dx中
                mov cx, dx                ;dx中储存着总余数传给cx
                mov dx, bx                ;bx储存的高位商传给dx
                ret                     ;返回call divdw处并向下执行

               
       
               
code ends
end start

人造人 发表于 2018-12-9 16:21:26

奥普瓯江 发表于 2018-12-9 16:00
我吧这个程序在分解一下并写了注释,但是还是会出现问题,跟上面那个问题一样,这回只处理一次处理的数据 ...

我已经开始研究上面那个程序了,我不想放弃目前的研究成果
^_^

人造人 发表于 2018-12-9 16:59:08

assume cs:code, ds:data

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)
stack ends

code segment

; 参数:
        ; dx:ax -> 被除数
        ; cx -> 除数
; 返回值:
        ; dx:ax -> 商
        ; cx -> 余数
divdw:
        push        bx
       
        push        ax
        mov        ax, dx
        xor        dx, dx
        div        cx        ; H/n
        mov        bx, ax
        pop        ax
        div        cx                ; (rem(H/n)*65536+L)/n
       
        mov        cx, dx
        mov        dx, bx
        pop        bx
        ret

year_str:
        mov        ax, word ptr ds:
        add        si, 2
        mov        dx, word ptr ds:
        add        si, 2
        xor        bx, bx
        push        cx
year_one:
        mov        cx, 10
        call        divdw
        push        cx
        inc        bx                ; 余数计数器
        cmp        ax, 0
        jne        year_one

        mov        cx, bx
        xor        di, di
year_four:
        pop        ax
        add        al, '0'
        mov        ah, 2                ; 绿色字体
        mov        word ptr es:, ax
        add        di, 2
        loop        year_four
       
        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        cx, 10
        mov        di, 0
        mov        si, 0
        xor        bp, bp
        call        year_str
       
        mov        ax, 4c00h
        int        21h
code ends
end start

人造人 发表于 2018-12-9 17:01:43

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)
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:
                add si, 2
                mov dx, word ptr ds:
                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:, al;把al数据输出到0b800h段中该段是显存段每行160个字节
                mov byte ptr es:, 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 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

人造人 发表于 2018-12-9 17:07:05

学会写注释
https://blog.csdn.net/ylforever/article/details/51171580

奥普瓯江 发表于 2018-12-9 22:52:27

人造人 发表于 2018-12-9 17:07
学会写注释
https://blog.csdn.net/ylforever/article/details/51171580

{:9_231:}这个代码注释的,我还得练习一下以后注意点这方面的是,努力改进自己写代码的习惯谢谢

奥普瓯江 发表于 2018-12-9 22:53:02

人造人 发表于 2018-12-9 17:01


这个代码我运行了还是哪的错误,这究竟是 为什么呢?麻烦了

人造人 发表于 2018-12-9 22:56:50

奥普瓯江 发表于 2018-12-9 22:53
这个代码我运行了还是哪的错误,这究竟是 为什么呢?麻烦了

什么?

奥普瓯江 发表于 2018-12-9 23:00:28

人造人 发表于 2018-12-9 22:56
什么?

就是还是会在divdw标记处的mov ax, dx处崩溃

人造人 发表于 2018-12-9 23:05:15

奥普瓯江 发表于 2018-12-9 23:00
就是还是会在divdw标记处的mov ax, dx处崩溃

我修改过的那两个代码?
弄一个gif(或者其他),把你从编译到运行的过程录下来,我看看

奥普瓯江 发表于 2018-12-9 23:21:54

人造人 发表于 2018-12-9 23:05
我修改过的那两个代码?
弄一个gif(或者其他),把你从编译到运行的过程录下来,我看看

嗯嗯使得我弄一个gif之类的东东传上来,您在帮我看看,应该除了那两处我逻辑上应该是没有错误的,我是这么认为的,麻烦了
页: [1] 2
查看完整版本: 为什么总是崩溃能这只是一个简单的mov ax, dx