课程设计1 -------------- 王爽 汇编语言

来源:互联网 发布:网络主持人是做什么 编辑:程序博客网 时间:2024/05/20 02:52
assume cs:code,ds:data,ss:stackdata 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 11452,14430,15257,17800data endsbyte_str segment    db 32 dup (0)byte_str endsstack segment    dw 64 dup (0)stack endscode segment   start:mov ax,data         mov es,ax         mov ax,byte_str         mov ds,ax         mov ax,stack         mov ss,ax         mov sp,128         mov cx,21         mov bx,0         mov si,0  ;指示年份和收入,都是4字节,采用相同方式定位         mov di,0  ;指示员工数         mov dh,2  ;初始化行号         mov dl,0         push dx       s:mov ax,es:[bx][si]         mov ds:[0],ax         mov ax,es:[bx][si+2]         mov ds:[2],ax         mov byte ptr ds:[4],0         pop dx     ;获得行号,开始为调用show_str显示年份做准备         push cx  ;保存cx值         push si  ;保存si值         mov dl,20   ;初始化年份的列号         mov cl,42h         mov si,0         call show_str         pop si         push dx         mov dx,es:[bx].84[si+2]         mov ax,es:[bx].84[si]         push si ;重新保护         mov si,0         call dtoc         pop si         pop dx         push si         mov dl,34         mov cl,71h         mov si,0         call show_str         push dx    ;主程序中保护dx,使dtoc子程序具有更大的使用范围和灵活性         mov dx,0         mov ax,es:[bx].168[di]   ;寻址员工数         mov si,0         call dtoc         pop dx         mov dl,70         mov cl,0c2h         mov si,0         call show_str         pop si ;寻址需要,拿出si         push dx  ;需要dx,保护原值         mov dx,es:[bx].84[si+2]         mov ax,es:[bx].84[si]         mov cx,es:[bx].168[di]         call divdw         push si         mov si,0         call dtoc         pop si         pop dx         push si         mov dl,88         mov cl,4ah         mov si,0         call show_str         pop si         pop cx         add si,4         add di,2         add dh,2   ;更新行         push dx         dec cx         jcxz over         jmp near ptr s    over:mov ax,4c00h         int 21h    dtoc:push bx         push cx    ;     push dx        ;把dx的保护放在主程序中         push di         mov bx,0     ;    mov dx,0     ;在主程序中为dx赋值      s1:mov cx,10         call divdw         add cl,30h         push cx         inc bx         mov cx,dx         jcxz ok0         jmp short s1     ok0:mov cx,ax         jcxz ok1         jmp short s1     ok1:mov di,si         mov cx,bx        ; mov bp,cx  ;用bp保存每个16位二进制数转成的十进制数的位数       m:pop dx         mov [di],dl         inc di         loop m         mov dl,0         mov [di],dl         pop di      ;   pop dx         pop cx         pop bx         ret    show_str:push bx             push dx             push es             push di             mov bx,cx             mov ax,0b800h             mov es,ax             mov di,0             mov ch,0             mov al,160             mul dh             mov dh,0             add ax,dx             and ax,0fffeh   ;保证起始地址从偶数字节开始             mov di,ax          s2:mov cl,[si]             jcxz ok2             mov es:[di],cl             mov es:[di].1,bl             inc si             add di,2             jmp short s2         ok2:pop di             pop es             pop dx             pop bx             ret     divdw:push bx   ;防溢出除法,被除数高16位dx,低16位ax,商存在dx-ax中,余数在cx中           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           retcode endsend start

问题总结:

1.主程序中loop循环体过大,loop s跳转指令只有8位位移,无法跳转到前面的s标记处。试了下loop near ptr s貌似没有这玩意。。最后用以下代码代替loop s功能,同时增加跳转位移。

dec cx         jcxz over         jmp near ptr s    over:mov ax,4c00h         int 21h
2.push和pop的使用,一定要配对出现,这没啥好说的。本程序设计三个子程序,存在一些寄存器的冲突,如si既用来寻址年份和收入,又是子程序dtoc和show_str被调用时的接口。cx作为循环体的计数部件,同时在子程序dtoc使用,又是divdw和show_str的接口。所以在子程序开始注意保护子程序内要修改的寄存器。在主程序内,调用子程序前,保护为子程序提供数据的接口寄存器。

3子程序接口定义一定要清晰。

divdw子程序:防止除法溢出的除。被除数高16位放在dx中,低16位在ax中。除数在cx中。商-->dx-ax ,余数-->cx

show_str:将起始地址在ds:[si]且以0结尾的字符串输出到屏幕。行数在dh,列数在dl,颜色在cl

dtoc:将高16位在dx,低16位在ax中的数转换成10进制,放到ds:[si]指定的位置,且以0结尾。

                    

原创粉丝点击