任務:將實驗7中的 Power idea 公司的數據按照圖10.2所示的格式在屏幕上顯示出來。
代碼實現
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'
;表示21年的21個字符串
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
;表示21年公司總收入的dword型數據
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
;表示21年公司僱員人數的21個word型數據
data ends
stack segment
db 20 dup (0)
stack ends
string segment
db 21 dup ('1970 0 0 0 ',0);這裏是40個字節一行
string ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,32;指針指向棧空間
mov ax,data
mov ds,ax
mov bx,0
mov di,0
mov ax,string
mov es,ax
mov si,0;指向數據空間
mov cx,21
s0:
push cx
mov ax,[bx+0]
mov es:[si],ax
add si,2
mov ax,[bx+2]
mov es:[si],ax;寫入年份
add si,2
add si,6;6字節不寫
mov ax,[bx+54H]
mov dx,[bx+54H+2]
call dtocdw;總收入10進制轉換成字符串並寫入
add si,10
mov ax,[di+0A8H]
call dtoc;僱員人數10進制轉換成字符串並寫入
add si,10
mov ax,[bx+54H+0]
mov dx,[bx+54H+2]
mov cx,[di+0A8H];這裏改變了cx,記得用後還原
call divdw;得到人均收入,(dx)=高16位,(ax)=低16位
call dtocdw;人均收入10進制轉換成字符串並寫入
add si,10;有一個0作爲結束標記,佔1字節,其餘9個空格,初始化時定義
add bx,4
add di,2
pop cx
loop s0
mov dh,4;更完善的可以之前做一下清屏工作
mov ax,string
mov ds,ax
mov bx,0
mov cx,21
s1:
push cx;這裏改變了cx,記得用後還原
mov dl,3
mov cl,00000010B
call show_str;調用show_str子程序,顯示一行數據
inc dh
inc bx
pop cx
loop s1
;mov ah,0
;int 16H;按任意鍵繼續,可直接雙擊運行
mov ax,4C00H
int 21H
;名稱:dtoc
;功能:將十進制數據轉化爲字符串
;參數:(ax)是十進制數據,ss:[sp]指向stack棧底,es:[si]指向string當前
;返回:在string標號內存空間的字符串,si不變
dtoc:
push ax
push bx
push cx
push dx
push es
mov bx,0
numToChar:
mov dx,0
mov cx,10
div cx
add dx,30H
push dx
inc bx;(bx)代表棧中有幾個字符
mov cx,ax;商爲0代表數字處理結束
jcxz stackToString
jmp short numToChar
stackToString:
mov cx,bx
mov bx,0
dtocS1:
pop ax
mov es:[bx+si],al;一次取一個字
inc bx
loop dtocS1
dtocOk:
pop es
pop dx
pop cx
pop bx
pop ax;注意按原本順序倒序出棧
ret
;名稱:dtocdw
;功能:將dword型十進制數據轉化爲字符串
;參數:(ax)是dword型十進制數據低16位,(dx)是dword型十進制數據高16位,es:[si]指向string當前
;返回:在string標號內存空間的字符串,si不變
dtocdw:
push ax
push bx
push cx
push dx
push es
mov bx,0
numToCharDw:
mov cx,10
call divdw;被除數在dx和ax中,餘數在cx中
add cx,30H
push cx
inc bx;(bx)代表棧中有幾個字符
mov cx,dx
or cx,ax;商爲0代表數字處理結束
jcxz stackToStringDw
jmp short numToCharDw
stackToStringDw:
mov cx,bx
mov bx,0
dtocdwS1:
pop ax
mov es:[bx+si],al;一次取一個字
inc bx
loop dtocdwS1
dtocdwOk:
pop es
pop dx
pop cx
pop bx
pop ax;注意按原本順序倒序出棧
ret
;名稱:divdw
;功能:除法,被除數32位,除數16位,商32位,餘數16位,不會溢出
;參數:(dx)=被除數的高16位,(ax)=被除數的低16位,(cx)=除數
;返回:(dx)=商的高16位,(ax)=商的低16位,(cx)=餘數
divdw:
push bx
push ax
mov ax,dx;(ax)=000FH
mov dx,0;(dx)=0
div cx;000FH÷0AH=0001H......5H,(ax)=0001H,(dx)=5H
mov bx,ax;(bx)=0001H
pop ax;(ax)=4240H
div cx;54240H÷0AH=86A0H......0H,(ax)=86A0H,(dx)=0H,(rem(H/N)*65536+L)/N的商
mov cx,dx;(cx)=0H;(rem(H/N)*65536+L)/N的餘數
mov dx,bx;(dx)=0001H,int(H/N)
pop bx;(bx)=0H
ret
;名稱:show_str
;功能:在屏幕指定位置,用指定顏色,顯示一個用0結尾的字符串
;參數:參數:(dh)=行號,(dl)=列號(0~80),(cl)=顏色,ds:[bx]:該字符串的首地址
;返回:顯示在屏幕上
show_str:
push cx
push ax
push dx
push es
push si;保存現場
mov ax,0B800H
mov es,ax
mov al,160
mul dh
sub ax,160
add dl,dl;最多80+80=160=0A0H,沒有進位問題
mov dh,0
add ax,dx;得到第dh行第dl列的的顯示器偏移地址,一列偏移2字節
mov si,ax;這時es:[si]指向了指定的顯示器地址
mov ah,cl;ah存放顏色格式,循環中不再改變
change:
mov cl,[bx]
mov ch,0
jcxz show_strOk;到0轉到標號ok執行
mov al,[bx];得到數據放入al
mov es:[si],ax
add si,2;下一個字母到下一列
inc bx
jmp short change;注意再跳到change標號,否則直接到ok標號處執行
show_strOk:
pop si
pop es
pop dx
pop ax
pop cx
ret
code ends
end start
運行結果
參考博客