assume cs:code
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,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,45257,17800
data ends
agency segment
db 8 dup(0)
agency ends
stack segment
dw 32 dup(0)
stack ends
code segment
;————————————————————————————主程序開始———————————————————————————————
start:
call clr_scr ;清屏
mov ax,agency
mov ds,ax ;設(shè)置agency為數(shù)據(jù)段
mov ax,data
mov es,ax ;設(shè)置data為擴(kuò)展段
mov si,0 ;用于數(shù)據(jù)段尋址
mov di,0 ;用于擴(kuò)展段尋址
mov bx,0 ;雇員數(shù)每個數(shù)據(jù)占2個字節(jié),與其他數(shù)據(jù)不同步,故單獨用bx尋址
mov dh,4 ;記錄行號,從顯示屏的第4行開始顯示
mov cx,21 ;顯示的行數(shù)為21行
x1:
push cx
;————————–年份——————————
mov ax,es:[di]
mov ds:[si],ax
mov ax,es:[di+2]
mov ds:[si+2],ax ;將年份存入數(shù)據(jù)段
mov byte ptr ds:[si+4],0
mov dl,0
mov cl,2 ;設(shè)置顯示參數(shù)
call show_str ;顯示年份
;————————–收入——————————
mov ax,es:[84+di]
push dx ;由于dh存儲行數(shù),下面的dtoc函數(shù)又要使用dx,故先將dx入棧
mov dx,es:[84+di+2]
call dtoc_dword ;將dx和ax聯(lián)合存儲的dword型數(shù)據(jù)轉(zhuǎn)成以ds:si為首地址,以0結(jié)尾的字符串
pop dx
mov dl,20
mov cl,2 ;設(shè)置顯示參數(shù)
call show_str ;顯示收入
;————————-雇員數(shù)—————————–
mov ax,es:[84+84+bx]
call dtoc_word ;將ax存儲的word型數(shù)據(jù)轉(zhuǎn)成以ds:si為首地址,以0結(jié)尾的字符串
mov dl,40
mov cl,2 ;設(shè)置顯示參數(shù)
call show_str;顯示雇員數(shù)
;————————人均收入—————————-
mov ax,es:[84+di]
push dx
mov dx,es:[84+di+2]
p word ptr es:[84+84+bx] ;人均收入=收入 雇員數(shù),結(jié)果存儲在ax中
call dtoc_word ;將ax存儲的word型數(shù)據(jù)轉(zhuǎn)成以ds:si為首地址,以0結(jié)尾的字符串
pop dx
mov dl,60
mov cl,2 ;設(shè)置顯示參數(shù)
call show_str;顯示人均收入
add di,4
add bx,2
add dh,1 ;設(shè)置下次循環(huán)參數(shù)變化
pop cx
loop x1
mov ax,4c00h
int 21h
;————————————————————————————主程序結(jié)束———————————————————————————————
;++++++++++++++++++++++++++++子函數(shù)開始+++++++++++++++++++++++++++++++
show_str:
;—————————————————————以0結(jié)尾的字符串顯示————————————————————————
;參數(shù):| (dh)=行號 | (dl)=列號 | ds:si指向字符串的首地址 |
;——————————————————————————————————————————————————————————————
push ax
push cx
push dx
push es
push si
push di ;數(shù)據(jù)保存
mov ax,0b800h
mov es,ax ;設(shè)置es為顯存段地址
mov al,160
mul dh ;每行占160字節(jié),故用dh*160
add dl,dl ;每列占2個字節(jié),故dl*2
mov dh,0
add ax,dx
mov di,ax ;設(shè)置di為顯存偏移地址
mov ah,cl ;用ah存放顏色屬性
show_str_x:
mov cl,ds:[si]
mov ch,0
jcxz show_str_f ;判斷字符串是否結(jié)束(以0結(jié)尾)
mov al,cl ;用al存放要顯示的字符
mov es:[di],ax ;向顯存中寫入內(nèi)容
inc si ;si指示字符串,每次移動一個字符
add di,2 ;di指示顯存位置,每次移動兩個字符
jmp show_str_x
show_str_f:
pop di
pop si
pop es
pop dx
pop cx
pop ax
ret ;數(shù)據(jù)恢復(fù),返回主程序
dtoc_word:
;———————————————word型數(shù)據(jù)轉(zhuǎn)十進(jìn)制字符串—————————————————
;參數(shù):| (ax)=word型數(shù)據(jù) | ds:si指向字符串的首地址 |
;——————————————————————————————————————————————————————
push ax
push bx
push cx
push dx
push si ;數(shù)據(jù)保存
mov bx,0 ;用bx來記錄要生成的字符串長度
dtoc_word_x:
mov dx,0
mov cx,10
p cx ;對ax進(jìn)行除10操作,得到其每一位數(shù)字的大小
mov cx,ax ;用cx記錄每次除10得到的商
add dx,’0′ ;將得到的每位數(shù)字轉(zhuǎn)為其對應(yīng)的ASCII碼
push dx ;將得到的每個ASCII碼依次入棧
inc bx ;每除一次,就有一個ASCII碼對應(yīng)的字符,故bx+1
jcxz dtoc_word_f ;通過判斷商是否為零來確定ax是否還能被10除
jmp dtoc_word_x
dtoc_word_f:
mov cx,bx ;將字符串長度賦給cx確定循環(huán)次數(shù)
dtoc_word_x1:
pop ds:[si] ;入棧時低位先入棧,故出棧時高位先出棧,無需改變順序
inc si
loop dtoc_word_x1
pop si
pop dx
pop cx
pop bx
pop ax
ret ;數(shù)據(jù)恢復(fù),返回主程序
dtoc_dword:
;—————————————————————————dword型數(shù)據(jù)轉(zhuǎn)十進(jìn)制字符串——————————————————————————————————————
;參數(shù):| (ax)=dword型數(shù)據(jù)低16位 | (dx)=dword型數(shù)據(jù)高16位 | ds:si指向字符串的首地址 |
;——————————————————————————————————————————————————————————————————————————————————————
push ax
push bx
push cx
push dx
push si ;數(shù)據(jù)保存
mov bx,0 ;用bx來記錄字符串長度
dtoc_dword_x:
s:
mov cx,10
call pdw ;由于存在除法溢出,故調(diào)用子函數(shù)來進(jìn)行除法操作
push cx
inc bx
mov cx,ax
jcxz ok
jmp short s
ok:
mov cx,bx
dtoc_dword_x1:
pop ds:[si]
add byte ptr ds:[si],’0′
inc si
loop dtoc_dword_x1 ;
pop si
pop dx
pop cx
pop bx
pop ax
ret ;數(shù)據(jù)恢復(fù),返回主程序
pdw:
;—————————————————————————————解決除法溢出問題———————————————————————————————————————————
;參數(shù):| (ax)=dword型數(shù)據(jù)低16位 | (dx)=dword型數(shù)據(jù)高16位 | ds:si指向字符串的首地址 |
;返回:| (ax)=結(jié)果的低16位 | (dx)=結(jié)果的高16位 | (cx)=余數(shù) |
;———————————————————————————————————————————————————————————————————————————————————————
push bx ;數(shù)據(jù)保存
push ax ;ax入棧(先進(jìn)行高16位除法)
mov ax,dx
mov dx,0
p cx ;高16位除法
mov bx,ax ;ax要出棧(進(jìn)行低16位除法),故用bx來暫存ax現(xiàn)在的數(shù)據(jù)(結(jié)果的高16位)
pop ax
p cx ;低16位除法,此時ax存放的是結(jié)果的低16位
mov cx,dx ;此時cx存放的是余數(shù)
mov dx,bx ;此時dx存放的是結(jié)果的高16位
pop bx
ret ;數(shù)據(jù)恢復(fù),返回主程序
clr_scr:
;————————清屏操作————————
; 無參數(shù)和返回值
;———————————————————————
push cx
push si
push ax
mov cx,4000
mov si,0
mov ax,0B800h
mov es,ax
s1:
mov es:[si],0
inc si
loop s1
pop ax
pop si
pop cx
ret
;++++++++++++++++++++++++++++子函數(shù)結(jié)束+++++++++++++++++++++++++++++++
code ends
end start