我的第一个程序

 

assume cs:codesg
datasg 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 11524,14430,15257,17800
datasg ends
tadlesg segment
    dd 21 dup (0,0,0,0,0,0,0,0)设定21个32字节的内存空间,每8个字节用来
tadlesg ends                   存放一组字符串,使每个字符串后面都剩一个
codesg segment                 零。因为最大的字符串是7位。
start: mov ax,datasg
       mov ds,ax
       mov ax,tadlesg
       mov es,ax
       mov bx,0
       mov di,0
       mov si,0
       mov bp,0
       mov cx,21
    s: mov ax,[bp]                      
       mov es:[bx],ax    
       mov ax,[bp+2]
       mov es:[bx+2],ax
       mov ax,[bp+84]         用BP+84定位DD型数据低8位的取数地址
       mov dx,[bp+86]         用BP+86定位DD型数据高8位的取数地址
       call dtoc              跳转到子程序,由子程序执行字符串转换和写入
       mov ax,[di+168]        用DI+168定位DW型数据的取数地址

       mov dx,0               把DW型数据定型成一个DD型数据,
       call dtoc          
       mov ax,[bp+84]         指定除数的位置

       mov dx,[bp+86]    
       div word ptr [di+168]  指定除数的位置
       mov dx,0               把求出的商定型为DD型的数据
       call dtoc              由子程序处理
       add di,2         
       add bp,4
       add si,8              3次循环后SI=24加8=32,定义下一行写入的地址。
       add bx,32             定位每次循环后,下一次要写入的地址       
       loop s

       mov ax,tadlesg
       mov ds,ax
       mov dh,2              定位显示的 行。
       mov bh,11001010b      定义成红底黄字
       mov si,0
       mov cx,21
   s2: mov dl,2              定义显示的 列。
       call show_str
       mov dl,14
       add si,8
       call show_str
       mov dl,24
       add si,8
       call show_str
       mov dl,35
       add si,8
       call show_str
       add si,8
       inc dh
       loop s2

       mov ax,4c00h
       int 21h

 dtoc: push di            字符转换的子程序。
       push bp 
       push cx
       push bx
       mov bx,10
       mov cx,0
       push cx            先入栈一个零,以后用JCXZ将字符串出栈的时候,   
   s0: mov di,ax          出栈零时,表示字符串已经全部出栈。
       mov ax,dx
       mov dx,0
       div bx
       mov bp,ax  
       mov ax,di
       div bx             除法溢出运算。
       add dx,30h         将余数加30H,转换成字符串。
       push dx            将字符入栈。
       mov dx,bp
       mov cx,ax          商为零的时候,循环结束,所有字符入栈。
       jcxz ok  
       jmp s0
   ok: add si,8           定位字符串要写入的地址。
       mov bx,0
   s1: mov cx,0
       pop cx             将字符串出栈。
       jcxz ok0           遇到零时,出栈结束,字符串出栈完毕。
       mov es:[bx+si],cx  把逆序求出的字符串,掉转顺序,写入指定位置。
       inc bx
       jmp s1
  ok0: pop bx
       pop cx
       pop bp
       pop di
       ret

show_str: push cx         以下是把数据写入显存的的子程序。
          push di
          push dx
          push bx
          mov ax,47104
          mov es,ax
          mov bl,160
          mov ax,0
          mov al,dh
          mul bl
          mov bp,ax
          mov dh,0
          add dl,dl
          mov di,dx
          mov ah,bh
          mov bx,0
          mov cx,0
      s4: mov cl,[bx+si]
          jcxz ok1
          mov es:[di+bp],cl
          mov es:[di+bp+1],ah
          add di,2
          inc bx
          jmp s4
     ok1: pop bx
          pop dx
          pop di
          pop cx
          ret
codesg ends
end start

 

 

 

 

        这是我的第一个程序, 当然不能把 Hello World 算在内。这是王爽老师的《王爽汇编》中的一个测试题目。当时我正在大连金石滩的一家网吧做网管。那时我在网上认识了一个网名叫做“猪头三”的汇编高手,他向我推荐了这本书。趁着春节期间学生放假,网吧不忙的时候,我开始了学习汇编。我大概用了差不多一个月的时间,学习了这本书四分之三的内容,然后就开始做这个题目。我用了差不多一周的时间做这个题目,在做这个题目的过程中,我收获了很多感悟。第一点是我理解了汇编中子程序的意义,它把一个特定的功能模块化,主程序可以在需要的时候随时调用,它使程序有了架构和清晰的流程。现在想想,汇编中的子程序就是C语言中的函数。第二点是我在做这个题目的过程中遇到了一个难题,就是除法溢出。我用两个16位的寄存器组成一个32位的被除数,除法运算之后会把商储存在一个特定的16位的寄存器中,这样当除数过小时,储存商的寄存器就溢出了,当时我毫无办法。后来我在网上找到了解决的方法,当时我感觉这个方法极其巧妙。那时的我认为一些打破常理但又能解决问题的巧妙方法完全是出于偶然,所以我更加感到这些方法的美妙。但是我现在有了新的看法,当一个人所寻求的答案在这个人的知识面以外的时候,问题在这个人眼里是无解的,但是,在他还没有透彻理解原理的情况下,让他偶然遇到了解决问题的答案,这个人就会觉得解决问题的方法妙不可言~~      最终,我完成了这个题目,上面的代码可以在debug中运行,可以看到几行几列闪闪发光的字符,从应用的角度看,这个程序没有一点实用价值,但是,却给了我坚定的信心。

 

        下面是我当时的笔记,重绘了我当时兴奋和喜悦的心情。当然也能看出当时的我有点故做谦虚~~

 

         可能还有许多要优化的地方,可我现在只能做成这样了。不怕大家笑话~我用了3天的时间,可能是我太苯了~呵呵~但没有关系,只要努力我还是可以做到的。想想程序好象比爱情简单多了~毕竟我可以通过努力来实现它,扯远了~呵呵。真的感谢这道题,要是没有它的陪伴,这几天我真的不知道该怎么过,现在看着DEBUG里闪闪发亮的字符,我真的很开心,因为我终于迈出了一步,我又可以向前进了~~~~!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值