[旧帖] [原创]菜鸟与你分享如何写程序 0.00元

绝版卡农 2011-4-10 12:25 2437
菜鸟与你分享如何写程序
    如何写程序是个很深的话题,不敢妄加臆断.在这里只想通过一个小程序与大家分享一下心得,纯属个人经验,不足之处还请老鸟斧正.
    相信很多和我一样的朋友曾经有这样的困惑,看书上的例子都懂,课后习题也大概的懂.或者看着书上的例子也能敲出一点东西来,但是一离
 开书本基本就没什么头绪了.感觉想写什么都无从下手,学了那么长时间那么多东西感觉无一点用处.于是乎,很苦恼的坐在电脑前发呆,看看网页
 ,玩玩游戏,慢慢的时间混过去了...
    首先我们要明白一点,程序是为了解决问题的.而解决问题就需要工具,语言就是写程序的工具,仅仅是个工具.一定要确定语言的地位,战略上藐视它,实践中重视它.
有些初学者被语言奴役了,学完这个学那个,整天被不同语言的语法区别搞的晕头转向.要意识到我们才是主人,语言才是奴隶.我们让它做什么,它就要不停的做,直到收到停止指令.
    编程重要的是思想.一个问题出来后,我们要想到怎么去解决它,然后用语言实现就好了.好了,废话说多了.举个简单的例子,王爽汇编书中的一个实验题,相信很多人看过或者正在看或者即将要看.
    题目:
                            '1. display      '
                            '2. brows        '
                            '3. replace      '
                            '4. modify       '
    要求:将上面4个字符串前四个字母变成大写.
    拿到题目后,我们开始糊涂了....
    不急,这时候我们有可能只记得一个最重要的知识点就是 二进制ASCII码 和11011111B,与(and)一下就变成大写了.这点应该是看书后的绝大多数人记得的吧.有时候,确实我们能想到的就是一些解决问题的关键步骤,但是具体实现完全没头绪.没事,想到这里我们立刻转变成程序语句.

                                 二进制ascii码 and 11011111B 
    
    到这里,自然的想到:哎呀,这样的东西,程序怎么能执行呢,管他呢,想到了就写出来吧.知道一点语法的知道,汇编不能识别(二进制ASCII码)这样的东西的.对了,汇编书不都是介绍了8086有很多寄存器么,既然是汇编给的那肯定能认识了吧.那就拿过来存放字符串吧,随便选个寄存器.就bx吧.
于是就变成:
            and [bx],11011111B

    问题又来了:and操作需要指明2个操作数的大小的,后面11011111B一看就知道是8位的.前面[bx]就需要我们指明了.其实这里不指明也不要紧,编译时,肯定出错一看提示就明白了.这也是我们经常遇到的这类情况,很正常的.我们还是指明下不用编译时候再回来改了.
            
     and byte ptr [bx],11011111B     ;指明[bx]"三维"是byte型的和后面的对应
            
    好了,这里实现了一个字符的大写转换,那要实现4个呢.那就循环一下吧
    我们希望bx从0变到3.那就每次循环加1吧,初始值设为0.
            mov cx,4  ;先设置一下循环次数
            mov bx,0  ;初始设为0,从第一个字母开始.
        s:  and byte ptr [bx],11011111B
            inc bx    ;每次循环+1,指向下个字母.
            loop s

    这时候看一下字符串,字母开始的位置并不是第1位而是地4位.那就加3吧(为什么加3?这个...幼儿园有的教.)
            mov cx,4  ;先设置一下循环次数
            mov bx,0  ;初始设为0,从第一个字母开始.
        s:  and byte ptr [bx+3],11011111B
            inc bx    ;每次循环+1,指向下个字母.
            loop s
          
    第一行前4个都变大写.有人要问:有4行呢,怎么办?头又要昏了.慢慢想,第一行前4个我都能变大写了,那把上面程序指向第2行再执行一次不就好了吗,第三第四也一样.这样一来4行只要外面再循环四次就好了.刚才已经用bx表示列数了,现在行循环又要个寄存器了.就选di表示行数.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            mov cx,4 ;4行循环4次
           mov di,0 ;从第一行开始
        s0: {每行变大写}
            add di,16  ;每次循环变到下一行.或者 add di,10h.每行大小是16个字节,不足的用空格填充的.
            loop s0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            上面我们已经把每行变大写的代码写出来了,直接替换吧
            
            mov cx,4 ;4行循环4次
            mov di,0 ;从第一行开始
        s0: mov cx,4  ;先设置一下循环次数
            mov bx,0  ;初始设为0
        s:  and byte ptr [bx+3+di],11011111B
            inc bx    ;每次循环+1,指向下个字母
            loop s
            add di,16  ;每次循环变到下一行.或者 add di,10h.每行大小是16个字节
            loop s0

   这里又有个问题了,第一次执行到loop s结束后cx已经变成0了,然后到 loop s0时候由于cx已经是0所以行数循环一次就退出了.
  这时候肯定有聪明的朋友说这个简单,由于cx用冲突了,反正寄存器多呢,把里面的cx换成dx什么的不就好了吗.这里人脑优点又体现了,本来我们想换成es,dx,甚至是奥特曼打小怪兽都可以的啊.只要存放下循环次数不和cx重复,就可以了吗.
  对不起,汇编里循环次数只能用cx存储.也就是说loop 只认识 cx.那我们就要把第一个cx在s循环前转存下,然后s循环结束后再放出来了.
  有2个方法:1.再选个寄存器,s循环结束后放回去.比如si, 2.放到堆栈里,s循环结束后出栈
        1.
              mov cx,4 ;4行循环4次
               mov di,0 ;从第一行开始
         s0: mov si,cx ;用si存放上面的cx
               mov cx,4  ;先设置一下循环次数
              mov bx,0  ;初始设为0
              s:  and byte ptr [bx+3+di],11011111B
              inc bx    ;每次循环+1,指向下个字母
              loop s
              mov cx,si ;存放的第一个cx值释放出来
              add di,16  ;每次循环变到下一行.或者 add di,10h
              loop s0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      2.
              mov cx,4 ;4行循环4次
              mov di,0 ;从第一行开始
          s0: push cx  ;cx入栈保存
              mov cx,4  ;先设置一下循环次数
              mov bx,0  ;初始设为0
        s:  and byte ptr [bx+3+di],11011111B
              inc bx    ;每次循环+1,指向下个字母
              loop s
              pop cx   ;cx出栈计数行号
              add di,16  ;每次循环变到下一行.或者 add di,10h
              loop s0

          哎呀,这里大功告成了.你看编程多简单.你看我们每行的前4个字符变大写了吧.
          我们都知道[bx]肯定是指向字符串首地址的啦,但是汇编很笨的.还需要我们告诉他.用到堆栈的还要告诉 汇编哪里是堆栈,哪里是代码段,程序从哪里开始.
1.          assume cs:code,ds:data
            data segment
                    db '1. display      '
                    db '2. brows        '
                    db '3. replace      '
                    db '4. modify       '
       data ends
       code segment
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       start:       mov ax,data
           mov ds,ax 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;把上面的拷贝过来,解决问题;;;;;;;;;;;;;;;;;;;;;;;;
           mov cx,4 ;4行循环4次
           mov di,0                         ;从第一行开始
           s0: mov si,cx                          ;用si存放上面的cx
           mov cx,4                         ;先设置一下循环次数
           mov bx,0                         ;初始设为0
           s:  and byte ptr [bx+3+di],11011111B
          inc bx                           ;每次循环+1,指向下个字母
          loop s
          mov cx,si                          ;存放的第一个cx值释放出来
          add di,16                        ;每次循环变到下一行
          loop s0
                        
          mov ax,4c00h ;程序返回
                int 21h
     code ends
     end start   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

2.    assume cs:code,ss:stack,ds:data
      stack segment
        dw 0,0,0,0,0,0,0,0
      stack ends
          
      data segment
        db '1. display      '
        db '2. brows        '
        db '3. replace      '
        db '4. modify       '
      data ends
          
      code segment
;;;;;;;;;;;;;;;;;;;;;;;;;;;;指明数据段;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        start:         mov ax,data
              mov ds,ax 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;指明堆栈;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
              mov ax,stack
              mov ss,ax
              mov sp,10h     ;指针指向栈底                  
                        
;;;;;;;;;;;;;;;;;;;;;;;;;;;循环开始;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
              mov cx,4 
              mov di,0 
              s0: push cx  
              mov cx,4  
              mov bx,0  
            s:  and byte ptr[bx+3+di],11011111B
              inc bx    
              loop s
              pop cx   
             add di,16  
             loop s0
                        
             mov ax,4c00h ;程序返回
             int 21h             
        code ends
        end start

  编译一下吧,debug载入,看看是不是前4个字母大写了.
  终于好了,一看表.哎呀,2小时过去了.不禁有人要想了,我2小时才写了这么个破程序.大多数人说不定几分钟,几秒钟就搞定了.
  这个吗,不能心急啊.慢慢来啊,你也会越来越熟练的.毕竟2小时你还憋出个东西来吗.大爷们不都是从孙子走过来的么?
  真的没有看着书就写出来了
  这个可以有,
  这个没有.
  这个真的可以有,
  这个真的没有.
  程序本身很简单,操作数组而已.关键是整个程序怎么写出来的,希望能对离开书就无从下手的朋友有点帮助.
  想到什么就用你所熟悉的语言写出来,不要怕错,怕自己写出来的不好,只要能解决问题就行,管它怎么实现呢.
  况且世上本来就没什么绝对的对和错,都是万恶的应试制度灌输的非对及错,非正及负,非生即死....
  打住,我承认鸡冻了.没想到我还是个愤青啊,防止被跨省...嘘...嘘...
  有时候想到的东西程序语言表达不出来也没关系,先画出来也好,只要自己能看明白思路.然后再查语法啊,api什么的实现.
  要敢想,大胆的去思考,不要被任何东西束缚你的思想.思想比知识更重要,这句话谁说的来着?呵呵,太熟悉了吧.
  菜鸟的感想,难免有不足之处.欢迎各位指正交流.

推荐:论坛大聚会| 看雪安全开发者峰会将于7月21号火热来袭!

最新回复 (38)
Mx¢Xgt 2011-4-10 12:37
2
友情支持下
高正直 2011-4-10 13:37
3
支持一下楼主
zsspanda 2011-4-10 14:15
4
lz说的确实有道理
周zhou周 2011-4-10 14:20
5
还好啦!用汇编搞哇!厉害!不过我学的汇编知识只是用来看汇编而不是用他来编程的
小小的心 2011-4-10 14:37
6
友情支持下~~~
炎冰 2011-4-10 14:40
7
路过,帮顶一下
Heytear 2011-4-10 22:50
8
大爷们不都是从孙子走过来的么?

这句话,好犀利~~我喜欢。。。。

汇编写程序。。。高端玩具。。感觉很难的啊~~
foxjinlin 2011-4-11 20:40
9
支持一下楼主

文章写得很好

比较喜欢这种循序渐进、步步为营的讲述风格
dartagnan 2011-4-11 22:48
10
汇编还是用来看程序好些吧!编程就算了,不过很赞同楼主的分享精神!
吉力有余 2011-4-11 23:48
11
作为一个新人,我得说楼主很有心,很强大,佩服。
表示感谢。
天涯路 2011-4-12 09:40
12
看看有都少kx了!
glxrz 2011-4-12 11:42
13
支持楼主了,
SKone 2011-4-27 22:30
14
终于有个我能看懂的,泪流满面。
琳庭紫微 2011-4-27 22:49
15
感谢LZ的讲解,很详细呀
KCobra 2011-4-27 22:58
16
顶下lz。。。加油
ssuclinux 2011-4-28 14:11
17
谢谢楼主分享
邋遢鬼 2011-4-28 14:30
18
楼主真是我的偶像呀
yuelongsha 2011-4-28 14:50
19
写得不错哦...学了这么久的语言..编程还是菜鸟,愧疚啊
jiaosc 2011-4-28 15:24
20
支持一下楼主
gongseoul 2011-4-28 17:45
21
练习练习成就自我
skan 2011-4-28 19:55
22
我晕,怪不得呢我看不懂...上面写些什么...原来是汇编啊... 哎 小白了
cryptonym 2011-4-28 20:27
23
大爷们不都是从孙子走过来的么?
========================
就喜欢这句。
熊猫正正 2011-4-28 23:55
24
通俗易懂,谢谢分享~~
xuez 2011-4-29 10:22
25
虽然看不懂、、、但还是要看地。。  学习下了。。。
pdiy 2011-4-29 12:02
26
居然没找到收藏功能,那就回帖顶一下,呵呵,挺好的文章
lyricC 2011-4-29 12:13
27
大爷的确都是从孙子走过来的,但不是所有从孙子走过来的人都能成为大爷
yuzhanhai 2011-4-29 13:27
28
准备学习汇编,大有启发
langyashan 2013-1-14 17:55
29
楼主的想法很好,多练习写呀,共勉
came 2013-1-15 10:01
30
友情支持楼主~~
leasr 2013-1-17 18:44
31
以前学过汇编,现在忘完了。。
南宫世家 2013-1-17 22:22
32
领教了。。。
frankxzb 2013-1-18 12:44
33
路过,帮顶下  汇编忘完了
leoaqi 2013-1-22 18:03
34
表示不会写汇编,不过受教了,是时候用心学习下汇编语言
linabc 2013-1-23 09:43
35
支持一下楼主。
grdxyxy 2013-1-23 09:46
36
学习了,汇编难学吗?
木影风神 2018-1-9 17:33
37
楼主的文风我很喜欢
凌乱的蚊子 2018-1-9 17:44
38
根本不知道汇编是什么东西  。只知道是一堆数字  字母。。但是所有的有价值没价值的东西都是数字跟字母。
阳天 2018-1-13 03:38
39
恭喜论坛改版成功  程序二开得不错
返回