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

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新留言
好友圈
文章收藏
友情链接

[2009-06-10 14:36] 课程设计一

图片载入中
说明:所有的子过程的参数均通过栈传递,在主过程(start)中,定义4个局部变量,用来记录行,列,颜色,和datas段的偏移地址,程序乱的我都不想在看第二遍!

注意:我是从第一行第一列开始显示,每个字段占10列
DATAS SEGMENT
    ;此处输入数据段代码  
    DB '1975','1976','1977','1978';16
    DD 16,22,382,1356;16
    DW 3,7,9,13;8 
DATAS ENDS

STACKS SEGMENT
    DB 80 DUP(0)
STACKS ENDS
TEMPS SEGMENT
        DB 20 DUP(0)
TEMPS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
        mov ax,DATAS
        mov ds,ax
        mov ax,STACKS
        mov ss,ax
        mov sp,80
        push bp
        mov bp,sp
        sub sp,8
        ;下面定义4个局部变量,其中前3个变量传个show_str
        mov word ptr [bp-2],1                        ;行
        mov word ptr [bp-4],1                ;列
        mov word ptr [bp-6],2                ;颜色
        mov word ptr [bp-8],0                ;数据段的偏移地址,请注意,这个变量值在主函数中调用
 
    mov cx,4
    ;★★★★★★★★★★年份★★★★★★★★★★★★
year:
        mov si,[bp-8];数据段的偏移地址
        mov ax,TEMPS
        mov es,ax
        mov di,0
        push cx;保存原有循环次数
        mov cx,2;设置循环次数
copy_word:
        mov ax,[si]
        mov es:[di],ax;把datas段数据送入es段
        sub cx,1
        jcxz copy_end
        add si,2
        add di,2
        jmp copy_word
copy_end:
        mov byte ptr [si],0;在字符串后加上一个空字符0
        pop cx        ;恢复原有循环次数
        push [bp-2]                ;行
    push [bp-4]                ;列
    push [bp-6]                ;颜色
        call show_str
        ;更新行号
        add word ptr [bp-2],1
        ;跟新偏移地址                                                                                                                                ;更新偏移地
        add word ptr [bp-8],4
        loop year
        ;★★★★★★★★★★收入★★★★★★★★★★★★
        ;我们要用到dtoc,他从尾写入字符串,最后在头加上一个0

        ;===========================
        ;BP                0
        ;IP                2
        ;低16位                4
        ;高16位                6
        ;===========================
        ;功能:把数字化成字符串
        ;参数:传入的32位的数字,要写入的字符串的首地址
        mov cx,4
        mov word ptr [bp-2],1                        ;行
        mov word ptr [bp-4],11                ;列
        mov word ptr [bp-6],2                ;颜色
                                                                ;偏移地址不变,因为此刻偏移地址已经指向了收入的第一个数据
income:
        ;更新局部变量
        
        ;下面给子过程dtoc的参数赋值
        mov si,[bp-8];注意他指向32位数,把偏移地址付给si
        push [si+2];这个32位数的高16
        push [si];低16
        call dtoc
        ;给show_str传参数
        push [bp-2]                ;行
    push [bp-4]                ;列
    push [bp-6]                ;颜色
        call show_str
        add [bp-8],4        ;更新偏移地址
        add [bp-2],1                ;更新行号
        loop income
        
        mov cx,4
        mov word ptr [bp-2],1                        ;行
        mov word ptr [bp-4],21                ;列
        mov word ptr [bp-6],2                ;颜色
                                                                ;偏移地址不变,因为此刻偏移地址已经指向了收入的第一个数据
hands:
        
        ;下面给子过程dtoc的参数赋值
        mov si,[bp-8];注意他指向16位数
        mov ax,0
        push ax;高16
        push [si];低16
        call dtoc
        ;给show_str传参数
        push [bp-2]                ;行
    push [bp-4]                ;列
    push [bp-6]                ;颜色
        call show_str
        add [bp-8],2        ;更新偏移地址
        add [bp-2],1                ;更新行号
        loop hands
        
        mov word ptr [bp-2],1                ;行
        mov word ptr [bp-4],31                ;列
        mov word ptr [bp-6],2                ;颜色
average:
        mov si,16
        mov di,32
        mov cx,4
get_ave:
        push cx
        push [di]
        push [si+2]
        push [si]
        call divdw;商放在dx,ax中
        pop cx
        push dx
        push ax
        call dtoc
        push [bp-2]                ;行
    push [bp-4]                ;列
    push [bp-6]                ;颜色
    call show_str
        add di,2
        add si,4
        add word ptr [bp-2],1
        loop get_ave

        pop bp
        MOV AH,4CH
    INT 21H
                
;bp
;ip
;颜色
;列
;行
;
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@show_str@@@@@@@@@@@@@@@@@@@@
show_str:
        push bp
        mov bp,sp
        push ds
        push es
        push si
        push di
        push ax
        push cx
        ;源数据段段地址和偏移地址
        mov si,0
        mov ax,TEMPS
        mov ds,ax
        ;目的显存的段地址
        mov ax,0b800h
        mov es,ax
        ;下面计算偏移地址,计算公式为:80×(r-1)×2+(c-1)×2 = 160×r+2×c-162 (其中r为行row,列为column)
        mov al,160
        ;在这里请注意,列数小于80
        mul byte ptr [bp+8]
        add ax,[bp+6]
        add ax,[bp+6]
        sub ax,162
        mov di,ax
        ;============计算偏移地址完毕============
        ;mov di,0
copy_char:
        mov cl,[si]
        mov ch,0
        jcxz done
        mov es:[di],cl

        mov ax,[bp+4];颜色值
        mov es:[di+1],al
        inc si
        add di,2
        jmp copy_char
done:
        pop cx
        pop ax
        pop di
        pop si
        pop es
        pop ds
        pop bp
        ret 6
;**********************************************************************************************        
;**********************************************************************************************
;需要的局部变量:1)段地址2)偏移地址
        ;===========================
        ;BP                0
        ;IP                2
        ;低16位                4
        ;高16位                6
        ;===========================
        ;功能:把数字化成字符串,注意,转化后的字符串写在temps段中,字符串后加上一个\0,标志结尾
        ;参数:传入的32位的数字,要写入的字符串的首地址
        ;无
        ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@dtoc@@@@@@@@@@@@@@@@@@@@
dtoc:
        push bp
        mov bp,sp
        push cx
        push es
        push di
        push ax
        push si
        
        mov ax,TEMPS
        mov es,ax
        mov di,0
        sub sp,2 ;定义一个局部变量,他用来计算这个字符串的字符个数
        mov word ptr [bp-12],0 ;初始化这个局部变量为0
        ;sub sp,6 在这里因为有3个局部变量,这三个局部变量用来
if_not_zero:
        mov ax,10
        push ax;压入除数
        push [bp+6];压入高16位
        push [bp+4];压入低16位
        call divdw        ;进行32位除法
        add word ptr [bp-12],1;把计数器加1,应该说没写入一次内存,就应该基数一次
        mov es:[di],cl ;把余数的低16位放入内存中,注意,此时放入内存的顺序是相反的
        add byte ptr es:[di],30H
        ;更新被除数
        mov [bp+6],dx
        mov [bp+4],ax
        ;========判断商是否为0==========
        or ax,dx
        mov cx,ax
        jcxz if_zero;如果为0
        ;==========判断结束 =========
        ;mov [bp+10],dx
        ;mov [bp+8],ax
        inc di
        jmp if_not_zero
if_zero:
        mov byte ptr es:[di+1],0
        ;下面把temps段全部放到堆栈中
        mov cx,[bp-12];计数器放入cx中
        mov si,0
word_into_stack:
        mov al,es:[si]
        push ax
        inc si
        loop word_into_stack
        
        ;把堆栈数在放入temps段中,即出栈
        mov cx,[bp-12]
        mov si,0
word_out_stack:
        pop ax
        mov es:[si],al
        inc si
        loop word_out_stack
        add sp,2;把计数器放入cx中
        pop si
        pop ax
        pop di
        pop es
        pop cx
        pop bp
        ret 4
        ;==================================
        ;bp        0
        ;IP        2
        ;低16        4
        ;高16        6
        ;除数        8
        ;==================================
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@divdw@@@@@@@@@@@@@@@@@@@@

        ;功能:进行32位和16位相除
        ;参数:32位被除数,16位除数
        ;返回值:32位商,其中ax低16,dx高16,cx16位余数
divdw:
        push bp
        mov bp,sp
        
        mov dx,0
        mov ax,[bp+6]
        div word ptr [bp+8];商ax,余数dx
        push ax
        mov ax,[bp+4];低16位ax,高16位dx
        div word ptr [bp+8];低16位在ax中,余数在dx中
        mov cx,dx
        pop dx
        pop bp
        ret 6
  
CODES ENDS
END START
评论次数(2)  |  浏览次数(675)  |  类型(汇编作业) |  收藏此文  | 

[  tomato   发表于  2009-06-10 16:45  ]

刚开始做思路是混乱的,多看几遍,多顺几遍思路,自然就知道怎么优化了。

[  younggay   发表于  2009-06-10 17:25  ]

首先恭喜博主完成课程设计一(虽然没有将全部的信息都显示完全),其实,做程序,尤其是设计一,我们最大的收获应该就是思维逻辑上的提升,大多数学习者做完后的感觉就是程序很乱,这就需要进行二次思考和分析,将程序逻辑弄顺喽,逻辑上清晰了,程序也就不乱了。
博主加油。

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