|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 18778160747 于 2018-6-1 22:14 编辑
纯手动,累计10小时完成
个人感受:开始做的时候思绪很乱,而后对于栈的使用愈发熟练,以及模块化设计的思想渗透。加上dos的单步加断点调试g命令的使用,慢慢的找出的问题细节,最后得以完成。感受最深的是模块化思想以及栈的作用。同时也感慨C语言等高级语言是多么多么多么的方便
代码如下:(纯手动,还可优化,但由于个人花时间太多,完成后就不大想再优化了,供后来读者参考)
assume cs:code,ss:stack
data segment
year db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
db '1993','1994','1995'
money dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
people dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
average dd 21 dup (0)
number dw 2 dup(0)
transfer db 10 dup(0)
data ends
对应结果
stack segment
db 32 dup (0)
stack ends
code segment
start: mov ax,data ;初始化,关联段与寄存器
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,31
call num
call aver ;计算平均值,将结果放入average
call show_year ;在屏幕上显示year
call show_money ;在屏幕上显示momey
call show_people ;在屏幕上显示people
call show_average ;在屏幕上显示average
mov ax,4c00h
int 21h
show_year: mov dh,2
mov dl,5
mov di,offset number
mov cx,ds:[di]
mov bp,0
s1: push cx
call site
mov ah,2
mov cx,4
call show
pop cx
inc dh
add bp,4
loop s1
ret
show_money: mov bx,offset money
mov si,offset transfer
mov bp,si
mov dh,2
mov dl,14
mov ah,2
mov di,offset number
mov cx,ds:[di]
lop4: push si
push cx
push dx
push ax
mov ax,[bx]
mov dx,[bx+2]
call tranf
mov cx,di
pop ax
pop dx
call site
call show
pop cx
pop si
add dh,1
add bx,4
loop lop4
ret
show_people: mov bx,offset people
mov si,offset transfer
mov bp,si
mov dh,2
mov dl,24
mov ah,2
mov di,offset number
mov cx,ds:[di]
lop5: push si
push cx
push dx
push ax
mov ax,[bx]
mov dx,0
call tranf
mov cx,di
pop ax
pop dx
call site
call show
pop cx
pop si
add dh,1
add bx,2
loop lop5
ret
show_average: mov bx,offset average
mov si,offset transfer
mov bp,si
mov dh,2
mov dl,34
mov ah,2
mov di,offset number
mov cx,ds:[di]
lop6: push si
push cx
push dx
push ax
mov ax,[bx]
mov dx,[bx+2]
call tranf
mov cx,di
pop ax
pop dx
call site
call show
pop cx
pop si
add dh,1
add bx,4
loop lop6
ret
;/**********************************************
;子函数说明:
;名称:aver
;功能:计算人均收入,适用本题
;传入参数:
;输出参数:
;***********************************************/
aver: mov bx,offset money
mov bp,offset people
mov di,offset number
mov cx,ds:[di]
mov di,0
lop1: push cx
mov ax,ds:[bx+di] ;给相应寄存器赋值,为divdw做准备
mov dx,ds:[bx+2+di]
mov cx,ds:[bp+si]
push bp
call divdw
mov bp,offset average
mov ds:[bp+di],ax
mov ds:[bp+2+di],dx
add si,2
add di,4
pop bp
pop cx
loop lop1
ret
;/**********************************************
;子函数说明:
;名称:num
;功能:计算数组数据个数,按题而定
;传入参数:
;输出参数:
;***********************************************/
num: push bx
push di
push ax
push dx
mov bx,offset money
mov di,offset number
mov ax,bx ;计算循环次数
mov cl,4
div cl
mov ah,0
mov ds:[di],ax
pop dx
pop ax
pop di
pop bx
ret
;/**********************************************
;子函数说明:
;名称:site
;功能:计算doc显存相应位置的偏移地址
;传入参数:行数dh、列数dl
;输出参数:对应偏移地址si
;***********************************************/
site: push dx
push ax
mov al,0a0h ;计算行偏移地址
mov ah,0
sub dh,1
mul dh
mov si,ax
mov al,2 ;计算列偏移地址
mov ah,0
sub dl,1
mul dl
add si,ax ;偏移地址总和
pop ax
pop dx
ret
;/**********************************************
;子函数说明:
;名称:tranf
;功能:;将双字型数字对应ASCIILL码存入transfer
;传入参数:低16位-ax、高16位-dx、transfer首地址si
;输出参数:对应ASCILL码长度-di
;***********************************************/
tranf: push ax
push dx
push si
push bp
push cx
mov di,0
mov cx,10
s3: cmp ax,0
je s4
cmp s5
s4: cmp dx,0
je reversed
s5: mov cx,10
call divdw
add cL,30h
mov ds:[si],cL
inc si
inc di
jmp s3
reversed: mov cx,di ;字符串逆序
mov bp,si
dec si
lop2: mov al,ds:[si]
push ax
dec si
loop lop2
mov cx,di
mov si,bp
dec si
lop3: pop ax
mov ds:[si],al
dec si
loop lop3
pop cx
pop bp
pop si
pop dx
pop ax
ret
;/**********************************************
;子函数说明:
;名称:divdw
;功能:无溢出16位整数除法
;传入参数:被除数低16位-ax、高16位-dx;除数-cx
;输出参数:商低16位-ax、高16位-dx;余数-cx
;***********************************************/
divdw: push bx ;无溢出32位除法
push ax
mov ax,dx
mov dx,0
div cx ;H/N
mov bx,ax ;ax,bx=(int)H/N ,dx=(rem)H/N
pop ax
div cx ;ax=L,dx=rem
mov cx,dx
mov dx,bx
pop bx
ret
;/**********************************************
;子函数说明:
;名称:show
;功能:在屏幕中显示一串字符串
;传入参数:对应的行列偏移地址si,字符串首偏移地址bp
; 字符串长度cx,显示属性ah
;输出参数:
;***********************************************/
show: push bx
push si
push bp
push cx
push ax
mov bx,0B800H
mov es,bx
s0: mov al,ds:[bp] ;送字符串字节
mov es:[si],al
mov es:[si+1],ah
add si,2
add bp,1
loop s0
pop ax
pop cx
pop bp
pop si
pop bx
ret
code ends
end start |
|