刚刚开始学汇编,遇到的第一个比较综合的程序,以下是源码,欢迎交流!
代码部分:
assume cs:code
data segment
dd 1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985
dd 1986,1987,1988,1989,1990,1991,1992,1993,1994,1995
;年份
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,2759000,3753000,4649000,5937000,7854000
;收入
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
;员工人数
table segment
dd 2 dup ( ) ;之后先把要显示的数据按十进制存到此段
;用零垫底 再用输出函数输出(第一段)
dw 21 dup ( ) ;将个人收入存到此段(第二段)
table ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0 ;ds指向data
mov ax,table
mov es,ax
mov di,0 ;es指向table第一段
mov cx,21 ;显示年份
mov dx,0101h
s2:
push dx
mov ax,ds:[si]
mov dx,ds:[si+2]
call far ptr doct
pop dx
call far ptr show
add si,4
add dx,0100h
loop s2
mov cx,21 ;显示收入
mov dx,0110h
mov si,0
s1:
push dx
mov ax,ds:[si+84]
mov dx,ds:[si+2+84]
call far ptr doct
pop dx
call far ptr show
add si,4
add dx,0100h
loop s1
mov cx,21 ;显示人数
mov dx,0120h
mov si,0
s3:
push dx
mov ax,ds:[si+168]
mov dx,0
call far ptr doct
pop dx
call far ptr show
add si,2
add dx,0100h
loop s3
mov si,0 ;将人均收入算出来存到table第二段
mov di,0
mov bx,0
mov cx,21
s7:
mov ax,ds:[bx+84]
mov dx,ds:[bx+2+84]
call far ptr doctc
add bx,4
loop s7
mov si,0 ;显示人均收入
mov di,0
mov bx,0
mov cx,21
s8:
mov dx,0130h
push dx
mov ax,es:[di+8]
mov dx,0
call far ptr doct
pop dx
call far ptr show
add di,2
add dx,0100h
loop s8
mov ax,4c00h
int 21h
doctc: ;计算人均收入的函数
push bp
push ax
push bx
push cx
push dx
push bx
mov bx,ds:[si+168]
mov bp,bx
pop bx
push ax
mov ax,dx
mov dx,0
div bp
mov bx,ax
mov dx,dx
pop ax
div bp
mov cx,dx
mov dx,bx
mov ax,ax
mov es:[di+8],ax
add si,2
add di,2
pop dx
pop cx
pop bx
pop ax
pop bp
retf
doct: ;将二进制转换为十进制ASCII码并存入table第一段,首位为零
push bp ;未将di入栈储存是因为show函数要继续使用di来确定数字位数
push ax
push bx
push cx
push dx
push si
push bx
mov bp,10
mov bx,0
mov es:[di],bl ;首位为零,后面用jcxz确定停止显示
inc di
pop bx
s:
push ax
mov ax,dx
mov dx,0
div bp
mov bx,ax
mov dx,dx
pop ax
div bp
mov cx,dx
mov dx,bx
mov ax,ax
add cx,30h
mov es:[di],cl
mov cx,ax
jcxz ok
inc di
jmp s
ok:
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
retf
show: ;将table第一段显示在屏幕上
push ds
push ax
push bx
push cx
push dx
push es
push si
push bp
mov ax,0b800h
mov si,0
mov cx,0
mov ds,ax
mov al,160
mul dh
mov bx,ax
mov al,2
mul dl
add bx,ax
mov al,2
help:
mov cl,es:[di]
jcxz exit
mov ds:[bx+si],cl
mov ds:[bx+si+1],al
dec di ;此时由于数字在table段是反的所以用自减
add si,2
jmp help
exit:
pop bp
pop si
pop es
pop dx
pop cx
pop bx
pop ax
pop ds
retf
code ends
end start
总结
这个代码用课余的时间写了将近一周,主要原因就是刚开始的流程没弄明白,该代码主要是三个函数,(数值显示函数;防止除法溢出的十进ASCII码转换函数;防溢出计算人均收入的函数),应该先搞明白流程,再一个一个去实现。