. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  课程设计一:一个看起来比较简洁的解决方案,使用一层循环解决该问题。  [待解决] 回复[ 1次 ]   点击[ 314次 ]  
zoudaokou2006
[帖 主]   [ 发表时间:2011-02-21 00:40 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:2
注册日期:2011-02-09 21:07
;Title:    Curriculum Design One
;File:     cd1.asm
;Function: Display the data of Power Idea in the form of Table Under DOS
;Note:     A Looking Concise Solution, Solve this Question in One Layer of Loop, but have to be Careful When Dealing with Registers.
;Author:   Chao Zhou
;Date:     02-21-2011

;标题:      课程设计一
;文件:      cd1.asm
;功能:      在DOS下以表格的形式显示Power Idea公司的数据
;注意:      一个看起来比较简洁的方案,使用一层循环解决这个问题,但是在处理寄存器的时候必须小心。
;作者:     周超
;日期:     02-21-2011

assume cs:codesg

;各组数据在data区的起始地址
YEAR_ARRRY         EQU         0H
SUMM_ARRAY        EQU         84
COUNT_ARRAY        EQU        168

;各列数据起始列
YEAR_LINE        EQU        6
SUMM_LINE         EQU         18
COUNT_LINE         EQU         30
AVER_LINE        EQU         42

data segment
        ;表示21年年份,字符串
        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年总收入,dword
        dd 16, 22, 382, 1356, 2390, 8000, 16000, 24486, 50065, 97479, 140417, 197514
        dd 345980, 590827, 803530, 1183000, 1843000, 2759000, 3753000, 4649000, 5937000
        
        ;雇员人数 dword
        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
        ;第一行显示内容
        LINE1 db '      Basic Situation Of The Power Idea Company    ',0          
        ;第二行显示内容
        LINE2 db '---------------------------------------------------------',0  
        ;第三行显示内容
        LINE3 db '      Year       Income      Number      Average',0           
table ends

;缓冲区,用于缓冲用作显示的字符串
buff segment
        db 100h dup(0)
buff ends

stack segment
        db 100h dup(0)
stack ends

codesg segment

;********************************************************************
;名称: main
;说明: 程序入口
;参数: 无
;返回: 无
;********************************************************************
main:
        mov ax, stack
        mov ss, ax
        mov sp, 20h

        ;------------表头------------
        mov ax, table
        mov ds, ax
        mov dl, 0
        mov si, offset LINE1
        mov dh, 0
        mov cl, 0CH
        call show_str                        ;显示表头第一行
        mov si, offset LINE2
        mov dh, 1
        mov cl, 0FH
        call show_str                  ;显示表头第二行
        mov si, offset LINE3
        mov dh, 2        
        mov cl, 0FH 
        call show_str                 ;显示表头第三行

        ;------------表内容------------
        mov ax, data
        mov es, ax

        ;ds指向缓冲区,后续用于缓冲用作显示的字符串
        mov ax, buff
        mov ds, ax

        ;------------按行显示表内容------------        
        mov di, 0
        mov bp, 0
        mov bl, 3                                ;从第三行开始显示表内容
        mov si, 0

        mov cx, 21
output_oneline:
        ;------------每次循环显示一行中的各列内容------------        
        push cx
        mov cl, 2                                ;颜色
        
        ;------------年份------------
        mov ax, es:YEAR_ARRRY[bp]
        mov dx, es:YEAR_ARRRY[bp + 2]
        mov ds:[0], ax
        mov ds:[2], dx
        mov ax, 0
        mov ds:[4], ax
        ;在屏幕上打印
        mov dh, bl
        mov dl, YEAR_LINE
        call show_str

        ;------------总收入------------
        mov ax, es:SUMM_ARRAY[bp]                ;低16位
        mov dx, es:SUMM_ARRAY[bp + 2]                ;高16位
        ;转换成字符串
        call dtoc 
        ;在屏幕上打印
        mov dh, bl  
        mov dl, SUMM_LINE
        call show_str
        
        ;------------人均收入------------
        mov ax, es:SUMM_ARRAY[bp]                ;被除数低16位
        mov dx, es:SUMM_ARRAY[bp + 2]                ;被除数高16位        
        div word ptr es:COUNT_ARRAY[di]        ;除数
        mov dx, 0
        ;转换成字符串
        call dtoc 
        ;在屏幕上打印
        mov dh, bl  
        mov dl, AVER_LINE
        call show_str        
        
        ;------------雇员人数------------
        mov ax, es:COUNT_ARRAY[di]                
        mov dx, 0
        ;转换成字符串
        call dtoc 
        ;在屏幕上打印
        mov dh, bl  
        mov dl, COUNT_LINE
        call show_str        
        
        inc bl
        add bp, 4
        add di, 2
        
        pop cx        
        loop output_oneline

        ;程序无限循环,不会退出,可以直接执行编译生成的文件,看到执行结果。
waitl:
        jmp waitl

        mov ax, 4c00h
        int 21h


;********************************************************************
;名称: show_str
;说明: 在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数: (dh) = 行号(取值范围0-24),(dl)=列号(取值范围0-79),(cl)=颜色,ds:si指向字符串的首地址
;返回: 无
;********************************************************************
show_str:
        push ax
        push bx
        push cx
        push es
        push si
        
        mov ax, 0B800H
        mov es, ax

        ;计算缓存首地址
        mov bx, 0
        mov al, 160
        mul dh
        add bx, ax
        mov al, 2
        mul dl
        add bx, ax

        mov al, cl                        ;用al缓存颜色
show_byte:
        mov cl, ds:[si]
        mov ch, 0
        jcxz show_str_end
        
        mov es:[bx], cl                        ;字符
        mov es:[bx + 1], al                ;颜色
        
        add bx, 2
        inc si
        jmp show_byte

show_str_end:
        pop si
        pop es
        pop cx
        pop bx
        pop ax
        ret


;********************************************************************
;名称: dtoc
;说明: 将dword型数据转变为表示十进制数的字符串,字符串以0为结尾符
;参数: (ax) = dword型数据低16位
;      (dx) = dword型数据高16位
;      ds:si指向字符串的首地址
;返回: 无
;********************************************************************
dtoc:
        push ax
        push bx
        push cx
        push dx
        push di
        push si

        mov bx, 0                ;累计位数        
div_loop:
        mov cx, 10                ;除数10
        call divdw
        push cx                        ;余数入栈
        inc bx
        mov cx, ax
        or cx, dx                ;ax、dx均为0,代表商为0
        jcxz end_div                ;商为0,结束循环
        jmp div_loop
end_div:
        
        mov cx, bx
make_str_loop:
        pop dx                        ;出栈,逆序获取余数,获得字符串
        add dl, 30h
        mov ds:[si], dl
        inc si
        loop make_str_loop
        mov al, 0
        mov ds:[si], al

        pop si
        pop di
        pop dx
        pop cx
        pop bx
        pop ax
        ret

        
;********************************************************************
;名称: divdw
;说明: 进行不会溢出的除法运算,被除数DWORD型,除数WORD型,结果DWORD型
;参数: (ax) = dword型数据低16位
;      (dx) = dword型数据高16位
;      (cx) = 除数
;结果: (ax) = 结果的低16位
;      (dx) = 结果的高16位
;      (cx) = 余数
;********************************************************************
divdw:
        push bx
        
        push ax                        ;保存被除数低16位L

        ;计算结果高16位int(H/N) * 65536
        mov ax, dx        
        mov dx, 0        
        div cx                ;结果高16位[int(H/N)]->ax,余数[rem(H/N)]->dx
        mov bx, ax        ;bx缓存结果高16位

        pop ax        ;被除数低16位L
        div cx                ;[rem(H/N)*65536 + L]/N,结果低16位->ax,余数->dx
        mov cx, dx        ;余数
        mov dx, bx        ;设置结果高16位

        pop bx
        ret

codesg ends
end        main
masmaster
[第1楼]   [ 回复时间:2011-02-22 09:38 ]   [引用]   [回复]   [ top ] 
荣誉值:268
信誉值:12
注册日期:2010-06-18 22:19
(__) 
  /oo\\________
  \ /     \---\
   \/    /  \  \
    \\_|___\\_|/  *
      ||  YY|  
      ||  ||   
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved