. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  课程设计1—完成—Mark  [待解决] 回复[ 12次 ]   点击[ 944次 ]  
kamjia
[帖 主]   [ 发表时间:2010-11-09 11:50 ]   [引用]   [回复]   [ top ] 
荣誉值:1
信誉值:2
注册日期:2009-05-25 18:12
经过好几天的痛苦挣扎,总算把课程设计1给完成了,呵呵,自己觉得程序可能有点儿啰嗦,但是,思路还比较清晰,发出来大家看看吧,自己也留下个脚印……

下面啰嗦一下这几天的总结:
1.子程序使用寄存器前一定要保存,避免在主程序中被调用时由于数据覆盖造成错误,其错误发现比较困难;
2.写程序时要养成写注释的好习惯,避免在程序调用的时候方便,同时以后在读程序时,让人快速理解程序的思路和流程;
3.程序的模块儿化优势:各个子程序功能分解,易于优化和扩展,方便调用
4.还有就是debug,虽然麻烦,但是很有效

就这些吧,具体还有好多体会,表达能力欠佳,就说这些吧···

下面是我的源代码(已测试结果无误):

assume cs:code,ds:data,ss:stack

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个字符(共84个字节,0-53H)
                                
                                dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
                                dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
                                ;以上是表示21年公司总收入的21个dword型数据(共84个字节,54H-A7H)
                                
                                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型数据(共42个字节,A8H-D1H)
        
data ends

stack segment

                                dw 80 dup (0)                ;定义栈段来暂存数据
                                
stack ends

table segment

                                db 672 dup (0)    ;定义21X32个字节来存放整个数据段的所有数据
                                
table ends

code segment

;-------------------------------------------------------------------------------------------
;                                                                                程序开始,初始化各段和寄存器
;-------------------------------------------------------------------------------------------
start:                mov ax,stack                        
                                mov ss,ax
                                mov sp,0a0h

                                mov ax,data
                                mov ds,ax
                                
                                mov ax,table
                                mov es,ax
                                
                                mov si,0
                                mov di,0
                                mov bx,0
                                
;-------------------------------------------------------------------------------------------
;                                                        将各项数据存入进table段中,以便稍后进行格式化
;-------------------------------------------------------------------------------------------                                
                                mov cx,21
loop1:                mov ax,0[bx]                                                ;将年份存入table段中,以0结束
                                mov dx,2[bx]
                                mov es:0[di],ax
                                mov es:2[di],dx
                                mov BYTE ptr es:4[di],0h
                                
                                mov ax,54h[bx]                                                ;将总收入存入table段中,以0结束
                                mov dx,56h[bx]
                                mov es:5[di],ax
                                mov es:7[di],dx
                                mov BYTE ptr es:15[di],0h
                                
                                mov ax,0a8h[si]                                        ;将雇员人数存入table段中,以0结束
                                mov es:16[di],ax
                                mov BYTE ptr es:21[di],0h
                                
                                mov ax,54h[bx]                                                ;计算出人均收入并存入table段中,以0结束
                                div word ptr ds:0a8h[si]                
                                mov es:22[di],ax
                                mov BYTE ptr es:32[di],0h
                                
                                add bx,4                                                                ;定位到下一个data段中的数据项
                                add di,32                                                        ;定位到下一个table段中的行
                                add si,2                                                                ;定位到下一个table段中的列
                                loop loop1
                                
;-------------------------------------------------------------------------------------------
;                                        格式化table段中的数据,将将之从第行第列开始显示到屏幕上
;-------------------------------------------------------------------------------------------                        
                                mov ax,table
                                mov ds,ax
                                mov si,0
                                
                                mov cx,21                                                        ;用循环将年份显示到第5行第1-11列
                                mov dh,5
                                mov dl,1
year:                        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop year
;----------------------------------------------------------------------------
;格式化总收入数据,并显示到第5行第12-22列
                                
                                mov cx,21
                                mov bx,5
tot_inco_1:        mov ax,ds:[bx]
                                mov dx,ds:2[bx]
                                call dtoc32
                                add bx,20h
                                loop tot_inco_1
                                
                                mov cx,21
                                mov si,5
                                mov dh,5
                                mov dl,12
tot_inco_2:        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop tot_inco_2

;----------------------------------------------------------------------------
;格式化雇员人数数据,并显示到第5行第23-33列
                                mov cx,21
                                mov bx,16
emp_1:                mov ax,ds:[bx]
                                mov dx,0
                                call dtoc32
                                add bx,20h
                                loop emp_1
                                
                                mov cx,21
                                mov si,16
                                mov dh,5
                                mov dl,23
emp_2:                push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop emp_2
                                
;----------------------------------------------------------------------------
;格式化人均收入数据,并显示到第5行第34列

                                mov cx,21
                                mov bx,22
avg_inco_1:        mov ax,ds:[bx]
                                mov dx,0
                                call dtoc32
                                add bx,20h
                                loop avg_inco_1
                                
                                mov cx,21
                                mov si,22
                                mov dh,5
                                mov dl,34
avg_inco_2:        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop avg_inco_2
                                
                                mov ax,4c00h                                                ;程序结束,返回
                                int 21h
;-----------------------------------------------------------------------------------
;说明:将dword型数据转变为表示十进制的字符串,字符串以0为结尾符
;参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,ds:si指向字符串的首地址
;返回:无
;-----------------------------------------------------------------------------------
dtoc32:                push dx                                ;将子程序里可能用到的寄存器入栈保存
                                push ax
                                push cx
                                push bx
                                push si
                                push di
                                
                                mov di,0                                ;;初始化di做计数器
                                
s1:                        mov cx,10
                                call divdw                        ;调用子程序divdw来做除法运算,求余
                                push cx                                ;将余数入栈保存
                                mov cx,dx
                                jcxz s2                                ;判断商的高16位是不是0,如果高16位是0则跳转到s2处去判断低位,不是0则继续执行
                                pop cx                                ;将余数出栈,做修改
                                add cx,30h
                                push cx                                ;再次将余数入栈保存
                                inc di                                
                                jmp short s1                ;跳到s1断续做除法
                                
s2:                        mov cx,ax                        ;判断商的低16位是不是0,如果低16位是0则跳转到s3处去,若不是0则继续执行
                                jcxz s3
                                pop cx
                                add cx,30h
                                push cx
                                inc di
                                jmp short s1                
                                
s3:                        pop cx                                ;由于结果的商即使是0,也要将当前的余数做修改保存的处理,则此处也要再一次做保存
                                add cx,30h
                                push cx
                                inc di
                                
                                mov cx,di
                                mov si,0
s4:                        pop ax
                                mov ds:[si][bx],al
                                inc si
                                loop s4
                                
                                mov BYTE ptr ds:[bx][si],0        ;在最后一位加入一个0来标识字符处理结束
                                jmp short ok
                                
ok:                        pop di
                                pop si
                                pop bx
                                pop cx
                                pop ax
                                pop dx
                                ret
                                
;-------------------------------------------------------------------------------------------                                        
;说明:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
;参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,(cx)=除数                        
;返回:(dx)=结果的高16位,(ax)=结果的低16位,(cx)=余数
;-------------------------------------------------------------------------------------------

divdw:                push bx                        ;将bx的值入栈保存
                                push ax                        ;先将低16位压栈保存

                                ;先计算高位除法
                                mov ax,dx                ;将高16位的数据放到ax中,做为被除数的低16位,来做16位除法运算
                                mov dx,0                        ;将被除数的高16设0处理
                                div cx
                                mov bx,ax           ;将商保存在bx寄存器中(此商稍后将会做为最后结果的高16位)
                                
                                ;再计算低位除法   
                                pop ax                        ;将之前压入栈的原数低16位的数据出栈
                                div cx
                                mov cx,dx                ;除法完成之后,将余数保存到cx中
                                mov dx,bx                ;将之前高位除法算的商放到dx中,做为结果的高16位(默认低16位已存放到了ax当中)
                                pop bx                        ;将bx的值还原
                                ret 

;----------------------------------------------------------------------------------------------------
;说明:在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数:(dh)=行号(0`24),(dl)=列号(0`79),(cl)=颜色,ds:si指向字符串的首地址
;结果:无返回值
;----------------------------------------------------------------------------------------------------
show_str:        push ax
                                push bx
                                push cx
                                push dx
                                push bp
                                push si
                                push di
                                
                                mov ax,0b800h
                                mov es,ax
                                mov di,0
                                
                                ;算出指定的位置的偏移地址
                                mov ax,0   
                                mov al,160                                ;每行有160个字节
                                dec dh                                        ;用行数减1乘以160个字节,算出整行的字节数
                                mul dh
                                mov bx,ax                                        ;将结果入栈保存起来
                                dec dl                                        ;将列减1乘以2得出第几列所占的字节数(显示1个字符需要用2个字节)
                                mov al,2
                                mul dl
                                add bx,ax                                ;将两数的结果相加,得出所规定的行、列所的偏移地址
                                
                                mov dl,cl                            ;因为S标号下将会用到CX值的判断,所以,在运行之前,将提供颜色值的寄存器CL保存下来
                s0:        mov cl,[si]
                                mov ch,0
                                jcxz return
                                mov al,[si]                                ;ax低8位用来保存字符的ascii码
                                mov ah,dl                                ;ax高8位用来保存字条的颜色信息
                                mov es:[bx][di],ax        ;将保存了ascii码和颜色的字符信息写入显存区
                                inc si                                        ;定位到下一个字符
                                add di,2                                        ;定位到下一个显存位
                                jmp s0
                                        
        return:        pop di
                                pop si
                                pop bp
                                pop dx
                                pop cx
                                pop bx
                                pop ax
                                ret
        
code ends

end start
cryking
[第1楼]   [ 回复时间:2010-11-15 14:29 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-11-01 10:55
条理很清晰,这样的代码 我喜欢。。。
asmcaicai
[第2楼]   [ 回复时间:2011-03-06 16:22 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2011-02-16 23:01
mark...
youguiqing
[第3楼]   [ 回复时间:2011-03-12 21:34 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2009-12-03 21:13
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,11430,15257,17800
data ends
stack segment
dw 16 dup (0)
stack ends
code segment
              start:mov ax,data
                  mov ds,ax
                   mov ax,stack
                   mov ss,ax
                   mov sp,32
                   mov ax,0b800h
                   mov es,ax
                   mov bx,0
                   mov bp,0
                   mov di,0
                   mov cx,21
                s: mov si,10      ;21次loop    注意SI的值为列数一定要清10后以bp为变量每次加160
                push cx     ;保存外层CX值
                   mov cx,4       ;内层年份4次
                   push bx    ;因为loop后bx会变,所以这里先保存
                n1:push [bx]        ;年份  从第10列开始显示    
                   pop es:[bp+si]
                   mov es:1[bp+si],02  ;加色
                   inc bx
                   add si,2
                   loop n1
                   pop bx
                   mov si,40     ;收入从40列开始
                   mov ax,84[bx]
                   mov dx,86[bx]
                   call dtoc
                   mov si,80    ;人数从80列开始
                   mov ax,168[di]
                   mov dx,0
                   call dtoc
                   mov si,120   ;人均收入从120列开始
                   mov ax,84[bx]
                   mov dx,86[bx]
                   mov cx,168[di]
                   call divdw
                   call dtoc
                   add bx,4     ;年份和收入为4字节,每次加4
                   add di,2     ;人数为2字节每次加2
                   add bp,160   ;bp每次加160用来换行
                   pop cx
                   loop s
                   mov ax,4c00h
                   int 21h
               
          divdw: push bx            ;这是大除法子程序dx+ax除以cx后商高为DX低位为AX余数为CX
              push ax
               mov ax,dx
               mov dx,0
               div cx
               mov bx,ax
               pop ax
               div cx
               mov cx,dx
               mov dx,bx
               pop bx
               ret
          dtoc:push bx     ;这是把高16位=dx低16位=ax的数转化为ascll码显示在屏幕上的子程序
                push cx
                  mov bx,0   ;一定要重置为0
            b1:  mov cx,10      ;注意用商来判断一定要先存余数后再判断
               call divdw
                 mov ch,02h ;加上显示的颜色
                 add cl,30h ;加上30h用ASCLL码显示
                 push cx   ;保存加色后的余数到载
                 inc bx  ;用来记录push了几次
                  mov cx,ax;下面是判断商是否为0
                  jcxz jdx
                jmp b1
          jdx:   mov cx,dx
               jcxz ok 
                 jmp b1
        ok:     mov cx,bx ;push几次直接pop 几次
           a1: pop es:[bp+si]   ;这里的bp和si直接来至主程序
                add si,2
                 loop a1
                 pop cx
                 pop bx
                 ret 
code ends
end start
youguiqing
[第4楼]   [ 回复时间:2011-03-12 21:36 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2009-12-03 21:13
楼主太长了吧
oldstone
[第5楼]   [ 回复时间:2011-03-13 20:46 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2011-02-04 09:04
3楼的,佩服!
hoxily
[第6楼]   [ 回复时间:2011-04-14 09:20 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-03-16 19:25
我也来晒晒我的成果.
;~~~~
assume cs:code,ds:data,ss:stack

data segment
    db '1975','1976','1977','1978','1979','1980','1981'
    db '1982','1983','1984','1985','1986','1987','1988'
    db '1989','1990','1991','1992','1993','1994','1995'
    ;以上是表示21年的21个字符串。
    
    dd 16,22,382,1356,2390,8000,16000,24486,50065
    dd 97479,140417,197514,345980,590827,803530
    dd 1183000,1843000,2759000,3753000,4649000
    dd 5937000
    ;以上是21年公司总收入的21个dword型数据。
    
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258
    dw 2793,4037,5635,8226,11542,14430,15257,17800
    ;以上是表示21年公司雇员人数的21个word型数据。

data ends

table segment
    db 21 dup('year summ ne ?? ')
    buffer byte 15 dup(0)
table ends

stack segment
    dw 256 dup(0)
stack ends

code segment
    start:
        mov ax,stack
        mov ss,ax
        mov sp,16;准备好栈空间
        mov ax,data
        mov ds,ax;让ds指向原始数据段
        mov ax,table
        mov es,ax;让es指向table段
        mov bx,0;让ds:bx指向data段的第一个数据 
        mov bp,0;让es:bp指向table段的第一行数据
        mov di,0;用于数据分析时偏移4个字节,针对年份和总收入
        mov si,0;用于数据分析时偏移2个字节,针对雇员数
        mov cx,21
    loop1:
        mov ax,[bx+di]
        mov es:[bp],ax
        mov ax,[bx+2+di]
        mov es:[bp+2],ax
        ;以上四句复制年份字符串到table
        mov ax,[bx+84+di]
        mov es:[bp+5],ax
        mov dx,[bx+86+di]
        mov es:[bp+7],dx
        ;以上四句复制收入到table,同时放好被除数
        div word ptr [bx+168+si]
        ;做除法,注意结果存在ax中
        mov es:[bp+0dh],ax
        ;将人均收入存入table
        mov ax,[bx+168+si]
        mov es:[bp+0ah],ax
        ;将雇员数存入table
        add bp,16
        add di,4
        add si,2
        loop loop1
    print:
        mov cx,21
        mov bp,0
        mov dh,0
        mov ax,table
        mov ds,ax
    loop2:
        mov dl,0
        mov byte ptr es:[bp+4],0
        push cx
        mov cl,00000010b
        mov si,bp
        call showstring
        add dl,20
        mov byte ptr es:[bp+4],' '
;~~~~~~~~~~~~~~~~~~~~~~~~~~~
        mov si,offset buffer
        mov ax,es:[bp+5]
        push dx
        mov dx,es:[bp+7]
        call dwordtoc
        pop dx
        call showstring
        add dl,20
;~~~~~~~~~~~~~~~~~~~~~~~~~~
        mov ax,es:[bp+0ah]
        push dx
        mov dx,0
        call dwordtoc
        pop dx
        call showstring
        add dl,20
;~~~~~~~~~~~~~~~~~~~~~~~~~~
        push dx
        mov dx,0
        mov ax,es:[bp+0dh]
        call dwordtoc
        pop dx
        call showstring
;~~~~~~~~~~~~~~~~~~~~~~~~~~
        add bp,16
        inc dh
        pop cx
        loop loop2
        mov ax,4c00h
        int 21h
;====================================
    showstring:
    ;功能:在指定的行列位置用指定的颜色显示
    ;     一个用0结束的字符串.
    ;参数:dh存储行号(0~24),dl存储列号(0~79)
    ;     cl存储颜色,ds:si指向字符串的首地址
    ;返回:无
        push dx
        push cx
        push si
        push ax
        push es
        push di;es:di用于现存定位
        push bx
        mov ax,0b800h
        mov es,ax;指向现存段
        mov al,dh
        mov bl,160
        mul bl;计算行偏移量
        mov di,ax
        add dl,dl
        mov dh,0
        add di,dx;计算列偏移量,最终得到dh,dl位置.
        mov ah,cl;保存颜色值到ah中.
    showstring_s:
        mov cx,0
        mov cl,[si]
        jcxz showstring_finish
        mov al,cl
        mov es:[di],ax
        add di,2;因为是连续地写入,所以当一行已满
                ;时会自动换到下一行.但是如此可能
                ;会写入到显示缓冲区的其他页.
        inc si
        jmp showstring_s
    showstring_finish:
        pop bx
        pop di
        pop es
        pop ax
        pop si
        pop cx
        pop dx
        ret
;====================================
    ;功能:将dword型数据转变为十进制数的字符
    ;     串,字符串以0结尾
    ;参数:dx:ax存储dword型数据
    ;     ds:si指向字符串的首地址
    ;返回:无
    dwordtoc:
        push bx
        push si
        push ax
        push dx
        push cx
        mov bx,0;set counter 0
    dwordtoc_s:
        mov cx,10;set divider
        call divdw
        inc bx
        push cx;store current remain digit
        mov cx,dx
        jcxz dwordtoc_test_ax
        jmp dwordtoc_s
    dwordtoc_test_ax:
        mov cx,ax
        jcxz dwordtoc_div_end
        jmp dwordtoc_s
    dwordtoc_div_end:
        mov cx,bx
    dwordtoc_s0:
        pop ax
        add ax,30h
        mov byte ptr [si],al
        inc si
        loop dwordtoc_s0
        mov byte ptr[si],0
        pop cx
        pop dx
        pop ax
        pop si
        pop bx
        ret
;====================================
    ;功能:进行不会产生溢出的除法运算,被除数为dword型,
    ;     除数为word型,结果为dword型.
    ;参数:ax存储dword的低16位
    ;     dx存储dword的高16位
    ;     cx存储除数
    ;返回:dx存储结果的高16位
    ;     ax存储结果的低16位
    ;     cx存储余数
    divdw:
        push bx
        mov bx,ax;保留低16位到bx中
        mov ax,dx
        mov dx,0
        div cx;做16位除法
        push ax;保存商的高16位到栈中
        mov ax,bx
        div cx;第二次16位除法
        mov cx,dx;将余数存入cx
        pop dx;还原商的高16位到dx
        pop bx
        ret
code ends
end start
mayjian
[第7楼]   [ 回复时间:2011-04-20 17:48 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2011-04-12 20:28
三楼做的不错,很简洁,但却是把show_str和dtoc函数融合在一起了。简洁了但失去了灵活性。
在第十行二十列显示颜色为红底蓝色的字符串,看不懂程序的就可能改错,但是楼主的就比较容易改动字符串的属性。
mayjian
[第8楼]   [ 回复时间:2011-04-20 17:51 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2011-04-12 20:28
编写任何程序,不仅要简洁,更要接口分明
csafei
[第9楼]   [ 回复时间:2011-07-09 12:42 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-06-06 17:11
三楼做的不错,很简洁,但却是把show_str和dtoc函数融合在一起了。简洁了但失去了灵活性。
在第十行二十列显示颜色为红底蓝色的字符串,看不懂程序的就可能改错,但是楼主的就比较容易改动字符串的属性。
------------------
回复:简洁了但失去了灵活性 不太明白怎么回事。俺也是这样的思路
vs9841
[第10楼]   [ 回复时间:2011-07-09 17:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29
也晒下我的代码。我的保留实验七的功能
==================
assume cs:codesg
datasg 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,15257,17800
datasg ends
table segment
     db 21 dup('year summ ne ?? ')
table ends
dtable segment                               ;临时存放一行table中的acsii数据
      db 16 dup (0)
dtable ends
stacksg segment
      db 30 dup (0)
stacksg ends
codesg segment
start:mov ax,datasg
      mov ds,ax
      mov ax,table
      mov es,ax
      mov ax,stacksg
      mov ss,ax
      mov sp,100
      mov bx,0
      mov di,0
      mov si,0
      mov cx,21
;***************************************************************************
;保留课实验七内容,不想重新编写了,复制数据到table表中
;***************************************************************************
sss:  mov ax,ds:[di]         ;复制年份的四个字节的字符串到table前四个字节中
      mov es:[bx].0h,ax
      mov ax,ds:[di].02h
      mov es:[bx].02h,ax
      mov es:[bx].04h,byte ptr 0     ;将空格变换为0                         

      mov ax,ds:[di].54h             ;复制公司每年总收入到table中
      mov es:[bx].05h,ax
      mov dx,ds:54h[di+2]
      mov es:[bx].07h,dx
      mov es:[bx].09h,byte ptr 0     ;将空格变换为0
      div word ptr ds:0A8h[si]       ;计算人均工资
      mov es:[bx].0Dh,ax             ;将计算人均工资的结果存入到table中
      
      
      mov ax,ds:0A8h[si]             ;复制公司雇员人数到table中
      mov es:[bx].0Ah,ax
      mov es:[bx].0ch,byte ptr 0     ;将空格变换为0
      mov es:[bx].0fh,byte ptr 0 
      

      add bx,10h
      add si,2
      add di,4
      loop sss
;**************************************************************************
;主程序用了21个循环
;**************************************************************************
      mov bx,0208h
      mov cx,21
      mov bp,0                
  ks: push cx
      mov ax,dtable
      mov ds,ax
      mov si,0
      mov ax,es:[bp+si]       ;将table中数据复制到缓存到dtable中,然后显示
      mov ds:[si],ax
      mov ax,es:[bp+si].2h
      mov ds:[si].2h,ax
      mov ds:[si].4h,byte ptr 0
      mov dh,bh
      mov dl,bl
      mov cl,2
      call show_str          ;显示年份
      
      push dx 
      mov ax,es:[bp+si].5h
      mov dx,es:[bp+si].7h
      call dtocdw
      pop dx
      add dl,10
      call show_str         ;显示收入
      
     
      mov ax,es:[bp+si].0ah
      call dtoc
      add dl,15
      call show_str         ;显示人数
      
      mov ax,es:[bp+si].0dh
      call dtoc
      add dl,15
      call show_str         ;显示人均收入

      add bh,01h
      add bp,10h
      pop cx
      loop ks


 mov ax,4c00h
 int 21h 
;========================================================
;dtocdw子程序
;********************************************************
;Name:     dtocdw
;Function: 将双字类型的数据转换成以0结尾的字符串
;参数:     ax=dword型数据的低16位
;          dx=dword型数据的高16位
;          ds:si返回转换后字符串的首地址
;********************************************************
dtocdw:            push cx
            push bx
            push si
            push dx
            push ds
            push ax

            mov bx,0
            push bx
dtocdws:    mov cx,10
            call divdw       ;调用32位被除数子程序后,axdx商
            add cx,30h       ;cx是余数
            push cx
            push ax
            push dx
            or ax,dx
            mov cx,ax
            pop dx
            pop ax
            jcxz dtocdwok2
            jmp short dtocdws
           
dtocdwok2:  pop cx
            mov ds:[si],cl
            jcxz dtocdwkkk
            inc si
            jmp short dtocdwok2
dtocdwkkk:  pop ax
            pop ds
            pop dx
            pop si
            pop bx
            pop cx
            ret
;=======================================================
;divdw子程序
;*******************************************************
;计算参数:
;ax=被除数低16位
;dx=被除数高16位
;cx=除数
;计算结果返回参数:
;ax=结果商的低16位
;dx=结果商的高16位
;cx=结果的余数
;*******************************************************
divdw:push bx
      mov bx,ax
      mov ax,dx
      mov dx,0
      div cx
      push ax
      mov ax,bx
      div cx
      mov cx,dx
      pop dx
      pop bx
      ret
;=======================================================
;****************************************************
;show_str dh=line number(0-24)
;         dl=column(0-79)
;         cl=color 
;****************************************************
show_str:     push bp
              push di
              push cx
              push dx
              push es
              push ax
              push si
              push bx

              mov ax,0b800h
              mov es,ax
              mov bl,2
              mov ax,0
              mov al,dl
              mul bl
              mov bp,ax
              mov al,0a0h
              mul dh
              mov di,ax          ;di=line number address
              mov ah,cl
  shows0:     mov al,[si]
                   mov cl,0
              mov ch,[si]
              jcxz showokk
              mov es:[bp+di],ax
              inc si
              add bp,2
              jmp short shows0
showokk:      pop bx
              pop si
              pop ax
              pop es
              pop dx
              pop cx
              pop di
              pop bp
              ret

;********************************************************
;Name:     dtoc
;Function: 将word类型的数据转换成以0结尾的字符串
;参数:     ax=word型数据
;          ds:si返回转换后字符串的首地址
;********************************************************
dtoc:   push bx
        push si
        push dx
        push ax
        push cx

        mov bx,0
        push bx
        mov dx,0
dtocs:        mov bx,10
        div bx
        mov cx,ax        ;ax=商 dx=余数
        add dx,30h
        push dx
        jcxz dtocok2
        mov dx,0
        jmp short dtocs
dtocok2:pop cx
        mov ds:[si],cl
        jcxz dtockkk
        inc si
        jmp short dtocok2
dtockkk:pop cx
        pop ax
        pop dx
        pop si
        pop bx
        ret   
codesg ends
end start
liash
[第11楼]   [ 回复时间:2011-08-07 16:43 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-07-29 21:21
。。。3楼的太牛逼了
baoyx007
[第12楼]   [ 回复时间:2011-10-26 21:13 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2011-08-31 20:36
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved