王爽.彙編.第三版.課程設計1.答案
阿新 • • 發佈:2019-01-28
日期:2017年7月3日
課程設計 1
任務:將實驗7中的Power idea公司的資料按照下圖所示的格式在螢幕上顯示出來
版本:beta 0.1
1、有時間再排版吧。都是用的第10章之前的指令。沒有優化程式碼
2、設計思路,為了簡單使用的是實驗七的程式碼,在生成每一行table後,直接將table中的一行作為print函式的引數;對齊方式為每10個字元佔一個欄位
3、每個函式的設計思路,註釋裡面in表示輸入引數,out表示輸出引數。in_out表示輸入輸出。
assume cs:code,ds:data,es:table
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個表示年收入的字串
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,45257,17800
;以上是21個僱傭人數
data ends
;臨時緩衝區
doublewordtostring_stack segment
db 10 dup(0)
doublewordtostring_stack ends
table segment
db 21 dup('year summ ne ?? ' )
table ends
string segment
db 47 dup(' '),0
string ends
color segment
db 01000010b,11000010b,01110001b
color ends
code segment
start:
;--------------------------------
; 一下將結構整合到table中
mov ax,data
mov es,ax ; 資訊來源
mov ax,table
mov ds,ax ; 資訊目的地
mov cx,21
mov si,0 ;年份的索引(0-21*4)
mov di,0 ;收入
mov bp,0 ;人數
mov bx,0 ;結果索引
mov dx, 0 ; 列印的行數
computerincome:
push cx
push dx
;year
mov al, es:[si]
mov ds:[bx],al
mov al,es:[si+1]
mov ds:[bx+1],al
mov al,es:[si+2]
mov ds:[bx+2],al
mov al,es:[si+3]
mov ds:[bx+3],al
;income, ready for div, set ax = so low word
mov ax,es:[di+84]
mov ds:[bx+5], ax
;ready for div, set dx = so high word
mov dx,es:[di+86]
mov ds:[bx+7], dx
;ne,ready for div, set cx = ne
mov cx,es:[bp+168]
mov ds:[bx+0ah], cx
;avrage
div cx
mov ds:[bx+0dh],ax
pop dx
pop cx
push dx
call print
pop dx
inc dh
add si, 4
add di, 4
add bp, 2
add bx, 010h
loop computerincome
mov ax, 4c00h
int 21h
;------------------------------------------------
; ds:bx為資料來源:按照實驗7的結構,21行,沒行16位元組,此處使用的就是那16位元組的資料
; dx:dh=row,dl=col
print:
push si
push cx
push bx
push es
push ds
push dx
push di
push bp
; 本行字串
mov ax, string
mov es, ax
mov si, 0
;-------------
; year
mov al , byte ptr ds:[bx]
mov byte ptr es:[si], al
mov al , byte ptr ds:[bx+1]
mov byte ptr es:[si+1], al
mov al , byte ptr ds:[bx+2]
mov byte ptr es:[si+2], al
mov al , byte ptr ds:[bx+3]
mov byte ptr es:[si+3], al
add si, 10 ; 對齊10個字元
;----------------
; all income
push ds
push bx
mov ax, ds:[bx+5] ;收入低16位
mov dx, ds:[bx+7] ;收入高16位
mov bx, es
mov ds, bx
call doublewordtostring
add si, 10 ; 對齊10個字元
pop bx
pop ds
;----------------
; 人數
push ds
push bx
push ax
mov ax, ds:[bx+0ah]
mov bx, es
mov ds, bx
call wordtostring
pop ax
pop bx
pop ds
add si, 10 ; 對齊10個字元
;-----------------
; 平均收入
push ds
push bx
mov cx, ds:[bx+0ah] ; 人數
call divdw
mov bx, es
mov ds, bx
call doublewordtostring
pop bx
pop ds
;------------
; ret
pop bp
pop di
pop dx
pop ds
pop es
pop bx
pop cx
pop si
;-----------------
; 開始列印
push ax
push ds
push si
push cx
mov ax, string
mov ds, ax
mov si, 0
mov cl, 01000010b
call writestring
mov al, ' '
call clearstring
pop cx
pop si
pop ds
pop ax
ret
;------------------------------------------------
; doubleword 轉化為字串
; ax,為16低位。
; dx,為16高位
;ds:si, in_out,字串輸出地址:eeeeeeeeerrorrr
doublewordtostring:
push bx
push dx
push cx
push ax
push es
push si
;-----------
;先逆序將所有數字轉成的字元放入堆疊
mov bx, 0
doublewordtostring_switch:
push cx
mov cx, 10
call divdw
;將除10後的商
add cx, 30h
push ax
push ds
mov ax, doublewordtostring_stack
mov ds, ax
mov ds:[bx],cx
pop ds
pop ax
pop cx
inc bx
cmp ax, 0
jne doublewordtostring_switch
cmp dx, 0
jne doublewordtostring_switch
;---------------------
;從臨時堆疊取出
mov cx, doublewordtostring_stack
mov es, cx
; bx為逆序的索引索引
mov cx, bx
dec bx
doublewordtostring_s:
mov al, byte ptr es:[bx]
mov byte ptr ds:[si], al
dec bx
inc si
loop doublewordtostring_s
;---------
pop si
pop es
pop ax
pop cx
pop dx
pop bx
ret
;end doublewordtostring
;-------------------------------------------
; word轉字串
;ax, in, number
;ds:si, in_out,字串輸出地址
wordtostring:
push bx
push dx
push cx
push ax
push ss
push sp
;先逆序將所有數字轉成的字元放入堆疊
mov bx, 0
wordtostring_switch:
mov dx, 0
push bx
mov bx, 10
div bx
pop bx
add dx, 30h
push dx ;放入堆疊
inc bx
mov cx, ax
jcxz wordtostring_okswitch
jmp wordtostring_switch
wordtostring_okswitch:
;從堆疊取出
mov cx, bx
mov bx, 0
wordtostring_s:
pop ax
mov byte ptr ds:[si+bx], al
inc bx
loop wordtostring_s
pop sp
pop ss
pop ax
pop cx
pop dx
pop bx
ret
;-- end wordtostring
;----------------------------------------------
; 沒有溢位的除法計算
;引數:
; (ax)= dword的低16位
; (dx)= dword的高16位
; (cx)= 除數
;輸出
; (ax)= 結果的低16位
; (dx)= 結果的高16位
; (cx)= 結果的餘數
divdw:
push es
push bx
push si
;save low word,ax
push ax
; ax = H, dx = 0, cx = L
mov ax, dx
mov dx, 0
; ax = H/N, dx = H%N
div cx
; save H/N
mov bx, ax
; dx is H%N, ax = low word同時作為下次除法的高位
pop ax
div cx ; ax=[rem(H/N)*65536+l]/N, dx = [rem(H/N)*65536+l]%N
; save 餘數
mov cx, dx
; ax = dx+H/N
mov dx, bx
pop si
pop bx
pop es
ret
;------------------------------------------------
;------------------------------------------------
; 下面的函式為向螢幕輸出字串
;------------------------------------------------
;------------------------------------------------
;------------------------------------------------
; 獲取指定index的顏色
; bx,in, color index
; al,out,color
getcolor:
;al儲存從顏色表中讀的顏色
push ds
push bx
mov ax, color
mov ds, ax
mov ah, 0
mov al, ds:[bx]
pop bx
pop ds
ret
;--------------------------------------------------
; 使用al清理字串
;ds:si,in, string's start pos
;al, string's defalt value
clearstring:
push ds
push si
push bx
push cx
mov bx, 0
mov cx, 0
clearstring_loop_set_0:
mov cl, ds:[si+bx]
jcxz clearstring_loop_ok
mov ds:[si+bx], al
inc bx
jmp clearstring_loop_set_0
clearstring_loop_ok:
pop cx
pop bx
pop si
pop ds
ret
;----------------------------------
;cl,in, color
;dx,in,dh=row,dl=col
;ds:si,in, string's start pos
writestring:
push si
push cx
push bx
push es
push ds
push dx
;視訊記憶體起始地址
mov bx, 0B800h
mov es, bx
; ref pos
call getpos
mov bx, ax
;al=cl,save color
mov al,cl
putchar:
mov ch,0
mov cl, ds:[si]
; 通過遇到字元0,跳出迴圈
jcxz okputchar
; 字元
mov byte ptr es:[bx], cl
; 顏色
mov byte ptr es:[bx+1], al
inc si
add bx, 2
jmp putchar
okputchar:
pop dx
pop ds
pop es
pop bx
pop cx
pop si
ret
;-------------------------
;dx,in,dh=row,dl=col
;ax,out,screen's ref pos
;ax = dh*160+dl
getpos:
push bx
push dx
;8位乘法不會改變dx的值
mov bl, 160
mov al,dh
mul bl
mov dh, 0
add ax, dx
pop dx
pop bx
ret
code ends
end start