汇编语言:课程设计1

来源:互联网 发布:远程软件哪个好用mac 编辑:程序博客网 时间:2024/05/20 03:42

汇编语言:课程设计1

本文内容来源于王爽《汇编语言(第3版)》

任务

将实验7(见原书)中Power idea 公司的数据按照如下格式在屏幕上显示出来。
这里写图片描述

提示

注意:有些数据已经超过16位了,因此要写一个新的子程序dtoc(见我的上一篇博文,或者见原书),我把它命名为ddtoc(详细信息见源代码,如果你看得懂我的中式英语的话)。在实现的过程中,要注意除法溢出的问题,因此还要调用自己之前实现的divdw子程序(见我的上一篇博文,或者见原书)
实现代码如下:

;---------------------------------------------------------------------;proc_name: ddtoc;function:  translate dword type data into a decimal string which;           ends with 0;interface: (ax) = the low 16 bit of the dword type data;           (dx) = the high 16 bit of the dword type data;           ds:si points to the first address of the string;return:    voidddtoc:          push    ax                push    cx                push    dx                push    si                push    bp                mov     bp,sp    ddtoc_s:    mov     cx,10                call    divdw                add     cx,'0'                push    cx                mov     cx,dx                add     cx,ax                jcxz    ddtoc_next                jmp     short ddtoc_s    ddtoc_next: pop     ax                mov     [si],al                mov     cx,sp                sub     cx,bp                jcxz    ddtoc_ok                inc     si                jmp     short ddtoc_next    ddtoc_ok:   mov     al,0                mov     [si+1],al                pop     bp                pop     si                pop     dx                pop     cx                pop     ax                ret;--------------------------------------------------------------------------;proc_name: divdw;function:  Division operation(avoid overflow);           the dividend is dword type and the divisor is word type;           the result is dword type, the remainder is word type.;interface: (ax) = the low 16 bit of the dividend;           (dx) = the high 16 bit of the dividend;           (cx) = divisor(word type);return:    (dx) = the high 16 bit of the result;           (ax) = the low 16 bit of the result;           (cx) = the remainderdivdw:      push    dx            push    ax            push    bp            mov     bp,sp            mov     dx,0            mov     ax,[bp+4]            div     cx            push    ax            mov     ax,[bp+2]            div     cx            mov     cx,dx            pop     dx            pop     bp            add     sp,4            ret;-----------------------------------------------------------------------------

代码实现

下面给出这个程序的完整代码:
附:由于汇编程序太过琐碎,就不给详细注释了,因为这段代码本身就是垃圾,各位看官扫一眼就可以,最后的效果之后给出(绝对辣眼睛!!!)
就算是给子程序传递参数,我也遇到了寄存器冲突问题,没办法,只能用堆栈保护。子程序show_str,dtoc都要有一段内存空间存放数据,因此我在table段后面放了20个字节的空间。
总而言之,代码乱的很,根本没法看,调试也极其困难,好歹运气好,满足了课程要求(吗?)

assume      cs:code,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'  ;offset address range:0-53h. informations of the years  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000  ;offset address range:54h-0a7h. information of the gross income each year  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226  dw 11542,14430,15257,17800  ;offset address range:0a8h-0d1h.information of the number of the emploees each yeardata endsstack       segment    db  256 dup(0)stack       endstable   segment    db 21 dup('year',0,'summ',0,'ne',0,'??',0)     ;offset address range:0~14fh    db 20 dup(?)    ;each line has 16byte spacetable   endscode        segmentmain:       mov     ax,data            mov     ds,ax            mov     ax,stack            mov     ss,ax            mov     sp,256            call    load_info            mov     ax,table            mov     ds,ax            mov     dh,0            mov     bx,0            mov     cx,21    s0:     push    cx            ;print the year            mov     si,bx            mov     dl,12            mov     cl,00000111b            call    show_str            mov     si,150h            ;print the gross income            add     dl,12            push    dx            add     bx,5            mov     ax,[bx]            mov     dx,[bx+2]            call    ddtoc            pop     dx            call    show_str            ;print the number of the emploees each year            add     dl,12            push    dx            add     bx,5            mov     dx,0            mov     ax,[bx]            call    ddtoc            pop     dx            call    show_str            ;print the average income            add     dl,12            push    dx            add     bx,3            mov     dx,0            mov     ax,[bx]            call    ddtoc            pop     dx            call    show_str            inc     dh            add     bx,3            pop     cx            loop    s0            mov     ax,4c00h            int     21h;---------------------------------------------------------------load_info:                  push    ax                push    bx                push    cx                push    dx                push    si                push    ds                push    es                mov     ax,data                mov     ds,ax                mov     ax,table                mov     es,ax                ;load the years                mov     si,0                mov     bx,0                mov     cx,21    load_info_s0:                 mov     ax,[si]                 ;load the former 2 bytes                mov     es:[bx],ax                      mov     ax,[si+2]                mov     es:[bx+2],ax            ;load the latter 2 bytes                add     si,4                add     bx,10h                loop    load_info_s0                ;load the gross income                mov     si,54h                mov     bx,0                mov     cx,21    load_infor_s1:                 mov     ax,[si]                 ;load the former 2 bytes                mov     es:[bx+5],ax                mov     ax,[si+2]                ;load the latter 2 bytes                mov     es:[bx+5+2],ax                add     si,4                add     bx,10h                loop    load_infor_s1                ;load the number of the emploees                mov     si,0a8h                mov     bx,0                mov     cx,21    load_infor_s2:                 mov     ax,[si]                mov     es:[bx+0ah],ax                add     si,2                add     bx,10h                loop    load_infor_s2                ;calculate and load the average income                mov     bx,0                mov     cx,21            s3: mov     ax,es:[bx+5]                mov     dx,es:[bx+5+2]                div     word ptr es:[bx+0ah]                mov     es:[bx+0dh],ax                add     bx,10h                loop    s3                pop     es                pop     ds                pop     si                pop     dx                pop     cx                pop     bx                pop     ax                ret     ;---------------------------------------------------------------------;proc_name: ddtoc;function:  translate dword type data into a decimal string which;           ends with 0;interface: (ax) = the low 16 bit of the dword type data;           (dx) = the high 16 bit of the dword type data;           ds:si points to the first address of the string;return:    voidddtoc:          push    ax                push    cx                push    dx                push    si                push    bp                mov     bp,sp    ddtoc_s:    mov     cx,10                call    divdw                add     cx,'0'                push    cx                mov     cx,dx                add     cx,ax                jcxz    ddtoc_next                jmp     short ddtoc_s    ddtoc_next: pop     ax                mov     [si],al                mov     cx,sp                sub     cx,bp                jcxz    ddtoc_ok                inc     si                jmp     short ddtoc_next    ddtoc_ok:   mov     al,0                mov     [si+1],al                pop     bp                pop     si                pop     dx                pop     cx                pop     ax                ret;--------------------------------------------------------------------------;proc_name: divdw;function:  Division operation(avoid overflow);           the dividend is dword type and the divisor is word type;           the result is dword type, the remainder is word type.;interface: (ax) = the low 16 bit of the dividend;           (dx) = the high 16 bit of the dividend;           (cx) = divisor(word type);return:    (dx) = the high 16 bit of the result;           (ax) = the low 16 bit of the result;           (cx) = the remainderdivdw:      push    dx            push    ax            push    bp            mov     bp,sp            mov     dx,0            mov     ax,[bp+4]            div     cx            push    ax            mov     ax,[bp+2]            div     cx            mov     cx,dx            pop     dx            pop     bp            add     sp,4            ret;-----------------------------------------------------------------------------;proc_name: show_str;function:  output a string with one color in a certain postion  ;interface: (dh) = row(0~24),(dl) = column(0~79);           (cl) = color, ds:si points to the first address of the string;return:    voidshow_str:       push    ax                push    bx                push    cx                push    dx                push    es                push    si                mov     ax,0b800h                mov     es,ax                ;set row                mov     al,160                mul     dh                mov     bx,ax                ;set column                mov     dh,0                add     dx,dx                mov     di,dx                ;output the string                mov     ah,clshow_str_s:     mov     al,[si]                mov     ch,0                mov     cl,al                jcxz    show_str_ok                mov     es:[bx+di],ax                inc     si                add     di,2                jmp     short show_str_sshow_str_ok:    pop     si                pop     es                pop     dx                pop     cx                pop     bx                pop     ax                      ret;------------------------------------------------------------------------code        endsend     main

输出的结果是这样的
这里写图片描述

这是什么鬼!怎么还有数据被”press any key to continue”覆盖掉了!
这是目前阶段没有办法避免的(按部就班地按照课本内容学习的话)。子程序show_str的原理就是向显存中直接写数据,如果之后数据被新内容覆盖掉,哥就无能为力了。

总结:

之前没觉得汇编有多麻烦,甚至还天真地认为只要把高级语言简单翻译一下,汇编程序就手到擒来了。我还是太天真了,汇编要注意的细枝末节太多,太琐碎了,我写出的程序也和垃圾没什么区别,反正每人认真看,我也只要能让代码运行就行了(这种思想很危险啊!!!)
其实在编程之前,我脑子中有个大概的框架和思路,用循环结构,每次输出一行的内容,在一行中依次输出需要得信息。但是一落实到代码实现,又不得不考虑底层的机器,各种保护寄存器,各种寻址方式,各种方式传参。最后形成的代码就是一个个零散的“部件”,完全看不出我脑海中原本朴素而简单的思想。总之,这次的程序设计,思路很简单,但是实现起来较为繁琐,这么简单的程序居然写了这么长。我写汇编的能力有了长足的进步(高兴)。
最后,我需要写两天高级语言冷静一下(笑)。

0 0
原创粉丝点击