zoukankan      html  css  js  c++  java
  • 汇编语言:简单的子程序设计

    汇编语言:简单的子程序设计

    本文内容来源于王爽《汇编语言(第三版)》实验10 编写子程序

    这次要求编写三个子程序,所有思路提示在书中给出了,需要了解的同学可以到书中寻找相关提示(尽管网上有电子书,但我强烈建议同学们花钱买实体书,而且还不贵)

    这些子程序的设计很简单,写关键代码之前,要记得用堆栈保护寄存器即可。
    下面给出具体实现的代码,不要笑话我的中式英语,我只是受中华文化影响比较深……(其实就是懒得打中国字,而且英文还蹩脚)

    第一个子程序——显示字符串

    设计思路:向80X25彩色字符模式显示缓冲区(内存地址从B800:0000到B800:7FFF)直接写入要显示的内容即可,具体内容见王爽的《汇编语言(第三版)》中的实验9补充材料。

    ;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

    第二个子程序——解决除法溢出问题

    由于除法指令div在某些情况下会出现溢出的状况(比如:(ax) = 0ffffh, (bx) = 1,
    DIV BL得到的商0ffffh,无法在寄存器al中存放)
    因此,有必要自己写一个子程序解决这一问题。书中给出了解决问题的公式,以及公式的证明,想知道的同学自己去翻书吧(我懒得打字了)

    ;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
                mov     bp,sp
                mov     dx,0
                mov     ax,[bp+2]
                div     cx
                push    ax
                mov     ax,[bp]
                div     cx
                mov     cx,dx
                pop     dx
                add     sp,4
                ret

    第三个子程序——数值显示

    思路:二进制转成十进制,在转换成数字字符,注意字符排列的顺序。用除法指令div要用32位除以16位,得到的余数序列要反转过来,才是真正要输出的顺序。为此,我用堆栈实现反转。最后,记得保护寄存器。
    配合第二个子程序,即可以在屏幕上显示数字了。

    ;proc_name: dtoc
    ;function:  translate word type data into a decimal digit string which
    ;           ends with 0
    ;interface: (ax) = data in word type
    ;           ds:si points to the first address to the string
    ;return:    void
    
    dtoc:           push    ax
                    push    bx
                    push    cx
                    push    dx
                    push    si
                    mov     bp,sp
    
                    mov     bx,10
                    mov     dx,0
            dtoc_s: div     bx
                    mov     cx,dx
                    add     cx,'0'
                    push    cx
                    mov     cx,ax
                    jcxz    dtoc_ok
                    mov     dx,0
                    jmp     dtoc_s
    
            dtoc_ok:    
                    pop     ax
                    mov     [si],al
                    mov     cx,bp
                    sub     cx,sp
                    jcxz    dtoc_out
                    inc     si
                    loop    dtoc_ok
    
            dtoc_out:
                    mov     al,0
                    mov     [si+1],al
    
                    pop     si
                    pop     dx
                    pop     cx
                    pop     bx
                    pop     ax
                    ret

    完整程序举例

    程序一

    功能:将12666以十进制形式打印在屏幕上

    assume      cs:code,ss:stack,ds:data
    
    stack       segment
        db 256 dup(?)
    stack       ends
    
    data        segment
        db 256 dup(?)
    data        ends
    
    code        segment
    
    main:       mov     ax,12666
                mov     bx,data
                mov     ds,bx
                mov     si,0
                call    dtoc
    
                mov     dh,8
                mov     dl,3
                mov     cl,2
                call    show_str
    
    
                mov     ax,4c00h
                int     21h
    ;---------------------------------
    ;proc_name: dtoc
    ;function:  translate word type data into a decimal digit string which
    ;           ends with 0
    ;interface: (ax) = data in word type
    ;           ds:si points to the first address to the string
    ;return:    void
    
    dtoc:           push    ax
                    push    bx
                    push    cx
                    push    dx
                    push    si
                    mov     bp,sp
    
                    mov     bx,10
                    mov     dx,0
            dtoc_s: div     bx
                    mov     cx,dx
                    add     cx,'0'
                    push    cx
                    mov     cx,ax
                    jcxz    dtoc_ok
                    mov     dx,0
                    jmp     dtoc_s
    
            dtoc_ok:    
                    pop     ax
                    mov     [si],al
                    mov     cx,bp
                    sub     cx,sp
                    jcxz    dtoc_out
                    inc     si
                    loop    dtoc_ok
    
            dtoc_out:
                    mov     al,0
                    mov     [si+1],al
    
                    pop     si
                    pop     dx
                    pop     cx
                    pop     bx
                    pop     ax
                    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
    

    程序二

        见下篇博文(笑)
    

    总结

    这篇博文其实是对王爽的《汇编语言(第三版)》的一篇推广文,这本书的确是一部初学者必读的好书,完全可以自学,比我们学校老师讲的好多了。
    汇编语言程序设计这门课虽然结束了,但我的汇编之旅才刚刚开始。说实话,在课上所学的东西连汇编的皮毛都没有,什么子程序传参,堆栈传参,中断向量表,我都没学会。现在我肚子里的墨水全是靠自学王爽的这本书的。
    现在还只是在8086实模式下编程,这是其他院校学过汇编这门课的大学生应该都掌握的,用中断的方式写点小程序,输出写彩色字符,做点动画,弄点音乐,这些都只是皮毛。而目前的我,连这些皮毛的做不到。
    总而言之,我会继续深入学习汇编语言,和汇编语言谈一场长久的恋爱。

  • 相关阅读:
    Java System.getProperty vs System.getenv
    Bring JavaScript to your Java enterprise with Vert.x
    es4x 引用外部jar 包以及集成typescrip
    cube.js 最近的一些更新
    es4x 调用其他三方jar 包
    graalvm native image 试用
    es4x 使用nodejs 开发vertx 应用框架试用
    clojure 环境搭建
    restql 学习三 查询语言简单说明
    restql 学习二 几种查询模式
  • 原文地址:https://www.cnblogs.com/wyf12138/p/6581529.html
Copyright © 2011-2022 走看看