zoukankan      html  css  js  c++  java
  • 汇编语言:课程设计1

    汇编语言:课程设计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:    void
    ddtoc:          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 remainder
    divdw:      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: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'
      ;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 year
    data ends
    
    stack       segment
        db  256 dup(0)
    stack       ends
    
    table   segment
        db 21 dup('year',0,'summ',0,'ne',0,'??',0) 
        ;offset address range:0~14fh
        db 20 dup(?)
        ;each line has 16byte space
    table   ends
    
    code        segment
    
    main:       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:    void
    ddtoc:          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 remainder
    divdw:      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:    void
    show_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,cl
    show_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_s
    
    show_str_ok:    pop     si
                    pop     es
                    pop     dx
                    pop     cx
                    pop     bx
                    pop     ax      
                    ret
    ;------------------------------------------------------------------------
    
    code        ends
    
    end     main

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

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

    总结:

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

  • 相关阅读:
    【原创】C++11:左值和右值(深度分析)
    【基础核心理论】运算符重载
    左值与右值引用 详解
    托盘图标编程
    C/C++ 数组与指针
    webpack 4.0改版问题
    mysql5.7安装记录
    equals方法
    【原创】IO流:读写操作研究(输入流)
    为什么重写equals一定要重写hashCode?
  • 原文地址:https://www.cnblogs.com/wyf12138/p/6581528.html
Copyright © 2011-2022 走看看