[049][汇编语言]课程设计 1 将实验7中的数据显示到屏幕上

课程设计1 :题目描述

任务:将实验7中的Power Idea公式的数据按照图10.2所示的格式在屏幕上显示出来。

实际运行

汇编语言 第三版 课程设计 1.png

完整源码

assume cs:code,ss:stack
    data segment
        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
        
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000

        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
    data ends
    
    cahe segment
        db 20 dup (0)
    cahe ends
    
    stack segment
        db 100 dup (0)
    stack ends
    code segment
        start:  mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,100
                mov ax,0B800H
                mov es,ax
                
                
                mov si,01E0H
                mov bx,0
                mov di,0
                mov cx,21
            s:  call year
                call mm
                call avg
                call summ
                add si,160
                add bx,4
                add di,2
                loop s

                mov ax,4c00H
                int 21H

                
        year:   mov al,02H
                
                mov ah,[bx+0]
                mov es:[si+0],ah
                mov es:[si+1],al
                
                mov ah,[bx+1]
                mov es:[si+2],ah
                mov es:[si+3],al
                                
                mov ah,[bx+2]
                mov es:[si+4],ah
                mov es:[si+5],al
                
                mov ah,[bx+3]
                mov es:[si+6],ah
                mov es:[si+7],al
                    
                ret     
                
                        
        mm:     push di
                push bx
                push ds
                push cx
                
                mov ax,[0A8H+di]
                mov bx,cahe
                mov ds,bx
                mov di,0
                
                call dtoc
                
                mov al,02H
                mov di,0
                mov bx,0
        mm_show:    mov cl,ds:[di]
                    mov ch,0
                    jcxz mm_end
                    mov es:[si+2EH+bx],cl
                    mov es:[si+2FH+bx],al
                    add bx,2
                    add di,1
                    jmp short mm_show
                
                
        mm_end: pop cx
                pop ds
                pop bx
                pop di

                ret
        
        dtoc:   push ax
                push bx
                push cx
                push dx
                push ds
                push di
                push ss
            
        
                mov dx,0
                mov bx,0AH
                
            s0: mov cx,ax
                jcxz ok
                div bx
                add dx,30H
                mov ds:[di],dx
                mov dx,0
                inc di
                jmp short s0
        
        ok:    mov bx,stack
                mov ss,bx
                mov bx,di
        
                mov cx,di
                mov di,0
                s1: push ds:[di]
                    inc di
                    loop s1
                
                mov cx,bx
                mov di,0
                s2: pop ds:[di]
                    inc di
                    loop s2 
                
                mov bx,0
                mov ds:[di],bx
                mov di,bx
                
                
                pop ss
                pop di
                pop ds
                pop dx
                pop cx
                pop bx
                pop ax
                ret

        
        avg:    push di
                push bx
                push ds
                push cx
                push ax
                push dx
                
                mov ax,[54H+bx]
                mov dx,[56H+bx]
                div word ptr ds:[0A8H+di]
                
                mov bx,cahe
                mov ds,bx
                mov di,0
                
                call dtoc
                
                mov al,02H
                mov di,0
                mov bx,0
        avg_show:   mov cl,ds:[di]
                    mov ch,0
                    jcxz avg_end
                    mov es:[si+44H+bx],cl
                    mov es:[si+45H+bx],al
                    add bx,2
                    add di,1
                    jmp short avg_show
                    
                
        avg_end:    pop dx
                    pop ax
                    pop cx
                    pop ds
                    pop bx
                    pop di          
                    ret 
        
        
        summ:           push di
                        push bx
                        push ds
                        push cx
                        push ax
                        push dx
                
                mov ax,[54H+bx]
                mov dx,[56H+bx]
                
                mov bx,cahe
                mov ds,bx
                mov di,0
                
                call dtoc2
                
                mov al,02H
                mov di,0
                mov bx,0
        summ_show:  mov cl,ds:[di]
                    mov ch,0
                    jcxz summ_end
                    mov es:[si+14H+bx],cl
                    mov es:[si+15H+bx],al
                    add bx,2
                    add di,1
                    jmp short summ_show
                    
                
        summ_end:   pop dx
                    pop ax
                    pop cx
                    pop ds
                    pop bx
                    pop di          
                    ret 

 
 dtoc2:         push ax
                push bx
                push cx
                push dx
                push ds
                push di
                push ss
            
                
            ss2:    mov cx,ax
                    jcxz ss3
                    mov cx,0AH
                    call divdw
                    add cx,30H
                    mov ds:[di],cx
                    inc di
                    jmp short ss2
                    
        
            ss3:    mov cx,dx
                    jcxz sok2
                    mov cx,0AH
                    call divdw
                    add cx,30H
                    mov ds:[di],cx
                    inc di
                    jmp short ss2
                
                
        sok2:   mov bx,stack
                mov ss,bx
                mov bx,di
        
                mov cx,di
                mov di,0
                ss12: push ds:[di]
                    inc di
                    loop ss12
                
                mov cx,bx
                mov di,0
                ss22: pop ds:[di]
                    inc di
                    loop ss22
                
                mov bx,0
                mov ds:[di],bx
                mov di,bx
                
                
                pop ss
                pop di
                pop ds
                pop dx
                pop cx
                pop bx
                pop ax
                ret

                
                
    divdw:  push bx
            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
        

    code ends
    end start

代码结构

  • data段 放全部的数据,之后是 cahe段缓冲区 放数值转换的ASCII码,最后是 stack段栈 空间,其中, cahe段缓冲区 不断被重复填写利用
DS寄存器
      读取数据时指向 DATA段
      用于子程序dtoc时,指向cahe缓冲区

ES寄存器
    全局指向显存 始终为 ES=B800H

  • 程序按照行输出数据,最外层的循环体现的就是21行(位于 start段
mov cx,21
s:              call year
                call mm
                call avg
                call summ
                add si,160    ;控制换行
                add bx,4        ;年份、收入的遍历
                add di,2        ;雇员人数的遍历
                loop s
  • 如何读取数据,以首行 1975 16 3 5举例
DS指向data段
db 型 
‘1’  [bx+0]
‘9’  [bx+1]
‘7’  [bx+2]
‘5’  [bx+3]

结合  add bx,4        ;年份、收入的遍历
--------------------------------------------------------------
dd型 32位
16 

  mov ax,[54H+bx]
  mov dx,[56H+bx]
结合  add bx,4        ;年份、收入的遍历
----------------------------------------------------------------
dw型 16位
3

[0A8H+di]
结合 add di,2        ;雇员人数的遍历

几段关键代码说明

  • CX 的在会溢出的除法运算中的多重角色(位于dtoc2
 ss2:    mov cx,ax
                    jcxz ss3
                    mov cx,0AH
                    call divdw
                    add cx,30H
                    mov ds:[di],cx
                    inc di
                    jmp short ss2
                    
        
            ss3:    mov cx,dx
                    jcxz sok2
                    mov cx,0AH
                    call divdw
                    add cx,30H
                    mov ds:[di],cx
                    inc di
                    jmp short ss2


溢出的除法运算
  商 存到 高16位(DX)、低16位(AX)
  余数 存到 (CX)
  因此,判断用商是否为零,就要判断两部分,高位以及低位
  所以,才有这个嵌套的循环
  ss2 看 AX是否为零,如果为零,则需要继续走到ss3 判断 DX是否零;
  都为零才是真正的商为零,可以跳转到除法的结束;
  AX和DX有任何一个不为0,就需要继续进行除法。

CX 在每次除法运算之后,会存着余数
  这个余数正是我们需要求到的位数
  在把这个位数保存到缓冲区 cahe之后,
  需要重新赋予 CX 作为除数的使命  mov CX,0AH
  这样除法才能整除继续下去。

子程序以及关键代码的参考

调试过程回忆

  • 栈空间不足,导致G命令卡死 DOSBOX
  • PUSH POP指令没有一 一对应,导致G命令卡死 DOSBOX
  • 会溢出的除法计算,将记录高16位的DX寄存器写成了BX
  • 标号命名混乱、重复
  • 复制有风险,粘贴需谨慎:一段运行正确的代码,复制粘贴也不一定就对,因为那段看上去可以运行正确的代码可能没有正确地返回寄存器内容,比如,BX在代码段1使用了、但是代码段2不用,这样的话, 在测试只有代码段1、2时,都不会出BUG,一旦复制代码段1的代码到代码段3,BX再次被使用就会暴露出来这个隐藏很深的BUG

代码段1



push ax
push bx

....
pop dx 【这里把应该写的BX写错成了DX】
pop ax
--------------------------------------------------------------------------
代码段3  使用 BX 【就会出现BUG,因为之前BX没有正确返回】

  同时如果代码段3 为了方便是复制的代码段1

  代码段3 也有
  push ax
  push bx

  ....
  pop dx 【这里把应该写的BX写错成了DX】
  pop ax
  如果代码段3,如果代码段3没有使用BX,
  后面用到BX的就会把这个隐藏的BUG深深的地传递下去

非常恐怖!

心得

  • 大力出奇迹
  • 发现从外往里包着写,比从下往上一直抽象要好写很多
  • 寄存器真的不够用,真的不够用,真的不够用!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342