王爽.汇编.第三版.课程设计1.答案

Poweridea公司财务数据展示

日期: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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值