汇编网首页登录博客注册
wangping198611的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
  •  在没有结果之前,千万不要放弃努力,因为结果未知,努力过了,即使失败了也不后悔,否则中途放弃只能是无尽的悔恨。
  • 『姓名』:王平
  • 『性别』:男『发送消息
  • 个人说明:一个人的失败是正常的,一个人的成功有2分努力,3分人脉加上5分运气和机遇,这里的2分努力是全力以赴,如果自我放弃随波如流,成功看起来离你很近,但是就是差那么0.1分,所以一定要全力以赴
  • 详细信息『加为好友』
学习动态
友情链接

[2009-03-27 00:40] 课程设计1 研究成功实现的代码

经过今天晚上对另外一个博主的课程设计1的代码进行了详细的分析,我把相关的注释加了上去,从头到尾明白了作者的设计思想,实在是受益匪浅,在使用汇编语言编程的时候应该注意尽量以最少使用寄存器来达到目的,为了最少使用寄存器,可以采用段内使用stack,开辟栈的方法来设计不同的动作。

在进入段前保存数据的时候要注意尽量不使用寄存器保存数据,因为很可能后来寄存器不够用,那么不使用寄存器的最好的解决办法就是使用栈,使用栈相对于使用内存而言要保护性更好。要注意压栈和弹栈的顺序问题。

另外还有一点就是明白了可以在汇编中开辟一段地址当作变量来使用,从而方便自己的开发。

分析的代码和注释如下:
assume cs:code 
asc segment 
  db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1;------ds:[15]为行变量 
asc ends 

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,2369,8000,16000,24486,50065,97479,140417,197514    
    dd 345980,590872,803530,1183000,1843000,2759000,3753000,4649000,59307000      
    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;------es
stack segment 
  db 32 dup (0) 
stack ends ;----ss

code segment 
start:    
    mov ax,data ;将data的数据段信息传入es为下一步做准备
    mov es,ax 
    mov ax,asc  ;一个变量,最后一个元素改变程序的偏移量的
    mov ds,ax 
    mov ax,stack ;准备了一个栈 
    mov ss,ax 
    mov sp,32 ;栈信息    
    mov si,0 
    mov di,0     
    mov cx,21 ;21年
     
s:   
    push cx     

    mov ax,es:[si];把data中的数据放在ds:[0][1]中放入 19 一共16个字节
    mov ds:[0],ax 
    mov ax,es:[si+2];将data中的 ds:[2][3]放入75 一共16个字节
    mov ds:[2],ax 
    mov byte ptr ds:[4],0 ;将第4个位置设置为0,目的是为了进行jcxz跳转
    mov dh,ds:[15]        ;变化位置的
    mov dl,0              ;变换位置的
    mov cl,2              ;指示颜色
    call show0str                   ;显示年份 
    
    
    
    mov ax,es:84[si]     ;设置dd的起始地址16,22....就是其中一个数字的代表
    mov dx,es:86[si]     ;一共4个单位代表数字
    call dtoc 
    mov dh,ds:[15]     
    mov dl,9 
    mov cl,3 
    call show0str                   ;显示收入 

    mov ax,es:168[di] 
    mov dx,0
    call dtoc 
    mov dh,ds:[15]     
    mov dl,39 
    mov cl,4 
    call show0str                    ;显示人数 

    mov ax,es:84[si] 
    mov dx,es:86[si] 
    div word ptr es:168[di] 
    sub dx,dx 
    call dtoc 
    mov dh,ds:[15]     
    mov dl,69 
    mov cl,5 
    call show0str                     ;计算并显示人均 
     
     
    pop cx 
    add si,4 
    add di,2 
    inc byte ptr ds:[15]     
    loop s 
    mov ax,4c00h 
    int 21h 

dtoc:;把所有可能用到的寄存器进栈,之后出来前再把所有的寄存器出栈    
    push ax 
    push bx 
    push cx 
    push dx 
    push si 
    push di 
     
    mov di,0 
dtocnum: 
    mov cx,10 ;设置除数是10
    call divdw 
    add cx,30h ;将16进制数字变成10进制
    inc di     ;设置下一步的循环次数
    push cx    ;把10进制的cx(余数)压入程序,此时是低位余数进入
    mov bx,ax ;把低位商保存在bx中
    add ax,dx ;dx是高位商,把低位商和高位商相加,-》
    mov cx,ax ;一直到商的和为0结束
    jcxz dtocend 
    mov ax,bx ;把低位商还原
    jmp dtocnum 
     
dtocend: 
    mov cx,di ;设置下一步出栈的循环次数
    mov si,0 
dtoccopy: 
    pop [si] 
    inc si 
    loop dtoccopy  
     
    pop di 
    pop si 
    pop dx 
    pop cx 
    pop bx 
    pop ax 
    ret             
     

divdw:    
    push bx 
     
    mov bx,ax ;ax储存的是低16位数字,dx中储存高16位数字
    mov ax,dx 
    sub dx,dx ;等同于mov dx,0
    div cx 
    push ax   ;ax储存的是高位商,还有dx是存储的余数
    mov ax,bx 
    div cx 
    mov cx,dx ;把余数给了cx,ax是低位商
    pop dx    ;把高位商放在dx中
     
    pop bx     
    ret 
   
show0str: 
    push ax     ;保存在主程序的任何信息,可以这样设计就是把所有的都给压栈
    push bx 
    push cx 
    push dx 
    push es 
    push si 
     
    mov al,160 ;从这里开始是showOstr程序的主体部分,此处为定位单位信息中的
    mul dh     ;结果存储在ax中
    mov bx,ax 
    mov al,2 
    mul dl 
    add bx,ax    ;定位信息一直持续到此处 
    mov ax,0b800h ;这一句和下一句是设置屏幕显示位置是在首页,设置了段地址
    mov es,ax     
    mov al,cl ;在这里cl中存储的是颜色的信息,在下一步要将数字信息传给cl,高位颜色信息,低位是数字信息
    mov ch,0 
    mov si,0  ;对应的是变量ds中的偏移地址
show0num: ;此处是打印信息,一次一个字符的打印,例如1975,共需要4次循环
    mov cl,[si] 
    mov ch,0     
    jcxz show0ok ;只是0的话就不打印直接进入showOok中
    mov ch,al 
    mov es:[bx],cx;将cx中的内容打印出来 
    inc si        ;打印下一个单元1975第一次打印1第二次准备打印9
    add bx,2      ;向右移动一个单元
    jmp show0num     
show0ok:     
    pop si 
    pop es 
    pop dx 
    pop cx 
    pop bx 
    pop ax 
    ret     
code ends 
end start
评论次数(2)  |  浏览次数(802)  |  类型(汇编作业) |  收藏此文  | 

[  younggay   发表于  2009-03-27 11:24  ]

恭喜博主终于搞定了,而且也理解了不少东西,这是最重要的,不过楼主程序中的显示有点不美观,呵呵。

[  maxm   发表于  2009-05-22 20:45  ]

研究研究你这个dtoc

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码