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

来源:互联网 发布:淘宝自定义属性怎么写 编辑:程序博客网 时间:2024/05/17 03:14

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

本文内容来源于王爽《汇编语言(第三版)》实验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:    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

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

由于除法指令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 remainderdivdw:      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:    voiddtoc:           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:datastack       segment    db 256 dup(?)stack       endsdata        segment    db 256 dup(?)data        endscode        segmentmain:       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:    voiddtoc:           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:    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                      retcode        endsend     main

程序二

    见下篇博文(笑)

总结

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

0 0
原创粉丝点击