Mindist的笔记 https://passport2.21ic.com/?594570 [收藏] [复制] [RSS] 我爱技术,我更爱生活!

日志

顺利完成汇编程序课程设计1

已有 774 次阅读2009-12-5 02:08 |系统分类:嵌入式系统

  几天以来因为有课有工作不能完全静下心来做这个设计,断断续续的调试,今天早上终于把它搞定啦!挺高兴的,hoho~~


  调试汇编程序很磨练人的耐性,急功近利或急于求成是学不到东西的,在调试过程中要摆好心态,抓住每一次碰到问题解决问题的机会,不轻易放弃。另外,调试汇编程序必须及其细心,着眼到每一条指令上,因为每一条指令都可能使你的程序崩溃。


  我想应该不只是调程序吧!只有用心调了才能真正学到东西,才能真正感受到调程序时的乐趣。这样的道理跟生活中也相通,再多华丽的文字也无法描述生活的美,只有我们用心生活,学着尝试在生活中做个有心人,怀着一颗对生活敏感的心去感受生活中的点滴——每一缕思绪、每一份感情、每一次心灵触动……你会发现生活给了我们太多太多……


  “生活不是有钱人的,也不是有权人的,生活是有心人的!”喜欢这句话。


  其实,技术是生活中的一道调味剂,也是感受生活的一种途径。看到我标题(长×宽×高)下面的签名了没?嘿嘿~“我爱技术,我更爱生活。。。”


  


  这次调试程序过程中有几点比较大的感触:


  1、写程序之前最好先布好设计框架,设计出流程图。小的程序还好,直接在脑子里面构思,大一点的程序就麻烦了,思路一乱起来,程序就跟着乱了,那样调试的时候就得吃苦头了。


  2、写程序过程时,应把一些功能指令,汇到一个子函数中,等要用到该功能时,再让子函数调用,尽量简化主函数,这样会使条理更清晰,这点跟C语言有点相识。


  3、写子程序时,之前用过的寄存器如果子函数中要用到,要记得将其压入堆栈,以免数据丢失。


  4、在使用push和pop指令时,注意顺序,并且之前压入多少数据,一般后面就要弹出多少数据,以免出现栈乱。


 


不说太多了,下面把我的程序和运行结果贴出来,供志同道合之士交流。


代码:


assume cs:code,ds:data,ss:stack,es:table


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'                                         
    ;以上是表示21年的21个字符串  


    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514  
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 
    ;以上是表示21年公司总收入的21个dword型数据            


    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800 
    ;以上是表示21年公司雇员人数的21个word型数据
data ends


table segment
    db 'year  earn     emp    ave '
    db 21 dup(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
table ends


stack segment
    db 256 dup(0)
stack ends


code segment
    start:
        mov ax,data;数据段
        mov es,ax
        mov bx,0
        mov bp,0
        mov ax,stack;栈段
        mov ss,ax
        mov sp,0
        mov ax,table;表格数据段
        mov ds,ax
        mov si,0
       
        mov cx,21      
        copydata:;将所有数据复制到表格数据段中
            push cx
           
            ;复制年份到表格数据段中
            mov ax,es:[bx]
            mov ds:01ah[si],ax
            mov ax,es:[bx+2]
            mov ds:01ah[si+2],ax
           
            ;复制收入到表格数据段中
            mov ax,es:054h[bx]
            mov ds:01ah[si+6],ax
            mov ax,es:054h[bx+2]
            mov ds:01ah[si+8],ax
                                             
            ;复制雇员数到表格数据段中
            mov ax,es:0a8h[bp]
            mov ds:01ah[si+0fh],ax
           
            ;计算出人均收入并存入表格数据段中
            mov ax,es:054h[bx]
            mov dx,es:056h[bx]
            mov cx,es:0a8h[bp]
            call divdw
            mov ds:01ah[si+016h],ax
            mov ds:01ah[si+018h],dl
           
            ;为下一次循环做准备
            add bx,4
            add bp,2
            add si,01ah 
           
            pop cx      
            loop copydata
           
        ;以下将表格中的数据转换成字符串形式,并将所有的数据显示出来
        mov ax,0b800h;使es:bx指向显示缓冲区
        mov es,ax
        mov bx,0
        mov si,0
              
        mov dh,0;初始化,第0行
        mov dl,0;初始化,第0列
        mov cx,22;表格数据共22行,循环22次
       
        ;以下将表格标题数据显示出来
        mov cl,07h;字符颜色属性(黑底白字)
        mov ah,cl;将字符的颜色属性存入ax的高八位
        mov cx,26;表格标题数据类型为字符串,25个字符
        table_title:
            mov al,ds:[si];将字符的ASCII码存入ax的低八位
            mov es:[bx],ax;将字符及其属性载入显存空间
            inc si
            add bx,2
            loop table_title
        mov bx,0a0h;显示缓冲区第1行
     mov cx,21
        showtable:
            push cx
           
            ;以下将年份数据显示出来
            mov cl,07h;字符颜色属性
            mov ah,cl;将字符的颜色属性存入ax的高八位
            mov cx,4;年份数据类型为字符串,4个字符
            year:
                mov al,ds:[si];将字符的ASCII码存入ax的低八位
                mov es:[bx],ax;将字符及其属性载入显存空间
                inc si
                add bx,2
                loop year        
               
            add si,2
            add bx,4 
            ;以下将收入数据转换成十进制并显示出来
            mov ax,ds:[si]
            mov dx,ds:[si+2]
            call dtoc          
            call show_str
           
            add si,9
            add bx,18
            ;以下将雇员数据转换成十进制并显示出来
            mov ax,ds:[si]
            mov dx,ds:[si+2]
            ;mov bx,10
            call dtoc          
            call show_str
               
            add si,7
            add bx,14
            ;以下将人均收入数据转换成十进制并显示出来
            mov ax,ds:[si]
            mov dl,ds:[si+2]
            mov dh,0
            call dtoc          
            call show_str
            ;inc dh;显示完一行换行
            ;mov dl,0;列不变
            add si,4
            add bx,6
            add bx,06eh;显示缓冲区每行可以显示80个字符,共160个字节,
                       ;已显示25个字符,剩55个字符,即110(06eh)个字节
           
            pop cx
            loop showtable


 mov ax,4c00h
 int 21h
       
     ;函数名:dtoc
     ;功能:将dword型数据转变为十进制数的字符串
     ;参数:(ax)=dword型数据的低16位
     ;      (dx)=dword型数据的高16位
     ;      ds:si指向字符串首地址
     ;返回:无
        dtoc:
            push bx
            push cx
            push dx
            push si
            push di
           
            mov bx,10
            mov di,0h;空操作符,用作字符串结束标志
            push di  
            s1:
                mov cx,bx      
                call divdw
                add cx,030h                  
                push cx;将取得的余数压入堆栈
                mov bx,10
                push ax
                add ax,dx
                mov cx,ax;将取得的商赋值给cx,用来判断取得的商是否为0
                pop ax
                inc cx;此处使cx加1是因为执行loop之前要先使cx减1      
                loop s1  
               
            s0:             
                pop bx
                mov cx,bx
             jcxz stop
             inc cx;此处使cx加1是因为执行loop之前要先使cx减1
             mov bh,0
             mov ds:[si],bl
             inc si  
                loop s0   


       stop:
           mov bh,0
             mov ds:[si],bl
           pop di
           pop si
           pop dx
           pop cx
           pop bx
           ret                           
           
        ;函数名:divdw
        ;功能:进行不会溢出的除法运算,被除数为dword型,除数为word型,结果为dword型
        ;参数:(ax)=dword型数据的低16位
        ;      (dx)=dword型数据的高16位
        ;      (cx)=除数
        ;返回:(dx)=结果的高16位
        ;      (ax)=结果的低16位
        ;      (cx)=余数       
        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
     
     ;函数名:show_str
     ;功能:在指定的位置,用指定的颜色,显示一个25字节的字符串
     ;参数:(cl)=颜色,ds:si指向字符串的首地址
     ;返回:无
     show_str: 
            ;将主程序用到的寄存器入栈
            push ax
            push bx
            push cx
            push dx
            push si
           
            s: 
                mov ah,07h          
                mov al,ds:[si];将字符的ASCII码存入ax的低八位
                ;以下判断al是否为0,为0则结束读取字符串
                mov cl,al
                mov ch,cl    
                jcxz ok
                mov word ptr es:[bx],ax;将字符及其属性载入显存空间
        
                inc si
                add bx,2
                loop s                
           
            ok:;将主程序用到的寄存器出栈
                ;pop cx;此处由于在“jcxz ok”之前进行了一次push cx,而后并无pop cx,在此将cx弹出堆栈
                pop si
                pop dx
                pop cx
                pop bx
                pop ax
           
            ret
code ends
end start  


 


运行结果:


图片


 


 


 


 


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)