- [游客] up~ 06/24 16:28
- [游客] 不错,加油~ 06/23 15:35
- [ptr] OV over flow NV no over flow 06/13 17:12
- [younggay] 首先恭喜博主完成课程设计一(虽然没有将全部的信息都显示完全),其实,做程序,尤其是设计一,我们最大的 06/10 17:25
- [tomato] 刚开始做思路是混乱的,多看几遍,多顺几遍思路,自然就知道怎么优化了。 06/10 16:45
- [游客] 正确。 06/10 16:31
- [ptr] 哈哈,真服了这位大哥,这么乱的代码…… 06/10 14:38
- [游客] 嗯。完成任务。 06/08 14:30
- [游客] 真够会偷懒的。呵呵 程序没问题。 06/08 11:02
[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
注意:我是从第一行第一列开始显示,每个字段占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) |
类型(汇编作业) |
收藏此文 |