⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w.asm

📁 hanoi塔游戏 差不多可以正常运行 请大家参考一下吧
💻 ASM
字号:
 .286                                   ;采用286指令系统。原因后述。   
    
  data   segment                   ;各变量的含义与VC版完全相同,   
      num1   db   0                     ;声明的先后顺序也完全一致。   
      num2   db   0   
      num3   db   0   
      n   db   0   
      char_a   dw   0                 ;char_a、char_b和char_c就是VC   
      char_b   dw   0                 ;版中的a、b和c三个字符型变量,   
      char_c   dw   0                 ;详见VC版子程序hanoi的声明。   
      x   dw   0   
      y   dw   0   
  data   ends   
    
  code   segment   
      main   proc   far             ;void   main()   
          assume   cs:code,ds:data   
    
          mov   ax,data             ;{   
          mov   ds,ax                 ;         (int   n;)   
                                            ;         cin>>n;   
          mov   ah,1                   ;输入第1个数。   
          int   21h   
          cmp   al,'0'               ;如果无效,则退出。   
          jb   exit   
          cmp   al,'9'   
          ja   exit   
          sub   al,30h   
          mov   n,al                   ;将第1个数暂存到n中。   
            
          int   21h                     ;输入第2个数,如果是回车,就把第1个数   
          cmp   al,0dh               ;当成个位,直接开始(jmp   begin)。   
          je   begin   
          cmp   al,'0'               ;如果无效,则退出。   
          jb   exit   
          cmp   al,'9'   
          ja   exit                     ;         if(n<1   ||   n>99){exit(1);}   
          sub   al,30h   
            
          mov   bl,n                   ;如果第2个数有效,那么就把第1个数(已   
          imul   bx,bx,10         ;暂存到n中)乘以10,加上第2个数。   
          mov   ah,0                   ;由于前面的imul是286指令,所以前面要   
          add   ax,bx                 ;写.286,以免出错。   
          mov   n,al   
    
          mov   ah,2                   ;回车换行。   
          mov   dl,0ah   
          int   21h   
          mov   dl,0dh   
          int   21h   
        
      begin:   
          mov   al,n   
          mov   num1,al             ;         num1=n;   
          mov   ah,0   
          push   ax                     ;对子程序hanoi的调用——是用堆栈的方式传   
          push   'a'                   ;递参数的。   
          push   'b'   
          push   'c'                   ;         hanoi(n,'a','b','c');   
          call   get_sys_time   ;输出系统时间,形式为“秒:百分之一秒”。   
          call   hanoi               ;调用hanio子程序,开始递归。   
          pop   ax                       ;出栈   
          pop   ax   
          pop   ax   
          pop   ax   
          mov   ah,2                   ;回车换行   
          mov   dl,0ah               ;         cout<<endl;   
          int   21h   
          mov   dl,0dh   
          int   21h   
          call   get_sys_time   ;再输出系统时间,以计算hanoi程序用时。   
      exit:                             ;退出程序。   
          mov   ah,4ch   
          int   21h   
      main   endp                     ;}     //main结束。   
    
    
      get_sys_time   proc   near   ;输出系统时间。   
          mov   ah,2ch                   ;调用功能2ch(获取系统时间)。   
          int   21h   
          mov   ch,dh                     ;dh存放当前的秒数。   
          call   outputch             ;按十进制输出ch中的两位数(秒数)。   
              mov   ah,2                   ;中间三行输出冒号。   
              mov   dl,':'   
              int   21h     
          mov   ah,2ch                   ;dl存放当前百分之一秒数。   
          int   21h   
          mov   ch,dl   
          call   outputch             ;输出之。   
          ret   
      get_sys_time   endp   
    
    
      hanoi   proc   near       ;void   hanoi(int   n,char   a,char   b,char   c)   
        call   printstats     ;{   
                                          ;           cout   <<endl<<"n="<<n<<"   abc="<<num1   
                                          ;           <<','<<num2<<','<<num3;   
          mov   bp,sp               ;sp不能直接用,所以要先传给bp。   
          mov   ax,[bp+2]       ;读取“进度”。   
          mov   char_c,ax   
          mov   ax,[bp+4]   
          mov   char_b,ax   
          mov   ax,[bp+6]   
          mov   char_a,ax   
          mov   ax,[bp+8]   
          mov   n,al           
          cmp   n,1                   ;   if(n==1)   
          jne   go_on   
              mov   ax,char_a   ;   {   
              mov   x,ax             ;   move子程序是用变量传递参数的,无须压栈。   
              mov   ax,char_c     
              mov   y,ax   
              call   move           ;           move(a,c);   
              jmp   sub_end       ;   }   
          go_on:                     ;   else   
              sub   n,1               ;   {     //else开始。   
              mov   al,n             ;   把n减去1,存入进度。   
              mov   ah,0   
              push   ax   
              mov   ax,char_a   
              push   ax   
              mov   ax,char_c   
              push   ax   
              mov   ax,char_b   
              push   ax   
    
              call   hanoi       ;           hanoi(n-1,a,c,b);   
                
              pop   ax               ;     读取进度。   
              mov   char_b,ax   
              pop   ax   
              mov   char_c,ax   
              pop   ax   
              mov   char_a,ax   
              pop   ax   
              mov   n,al   
                  
              mov   ax,char_a   
              mov   x,ax   
              mov   ax,char_c   
              mov   y,ax   
              call   move         ;           move(a,c);   
                
              mov   al,n           ;     保存进度。   
              mov   ah,0   
              push   ax   
              mov   ax,char_b   
              push   ax   
              mov   ax,char_a   
              push   ax   
              mov   ax,char_c   
              push   ax   
                
              call   hanoi     ;           hanoi(n-1,b,a,c);   
    
              pop   ax             ;       读取进度。   
              mov   char_c,ax   
              pop   ax   
              mov   char_a,ax   
              pop   ax   
              mov   char_b,ax   
              pop   ax   
              mov   n,al   
              add   n,1           ;       由于先前n已被减1,故此处要恢复n原值。   
    
          sub_end:             ;   }     //else结束。   
            ;call   printstats   ;cout   <<endl<<"n="<<n<<"   abc="<<num1   
              ret                           ;           <<','<<num2<<','<<num3;   
      hanoi   endp             ;}     //hanoi结束。   
    
    
      move   proc   near     ;void   move(char   x,char   y)   
          cmp   x,'a'           ;{   
              je   subnum1     ;         if   (x=='a')   {--num1;}   
          cmp   x,'b'           ;         if   (x=='b')   {--num2;}   
              je   subnum2   
          cmp   x,'c'           ;         if   (x=='c')   {--num3;}   
              je   subnum3   
          subnum1:   
              sub   num1,1   
              jmp   add_nums   
          subnum2:   
              sub   num2,1   
              jmp   add_nums   
          subnum3:   
              sub   num3,1   
              jmp   add_nums   
          add_nums:   
          cmp   y,'a'           ;         if   (y=='a')   {++num1;}   
              je   addnum1   
          cmp   y,'b'           ;         if   (y=='b')   {++num2;}   
              je   addnum2   
          cmp   y,'c'           ;         if   (y=='c')   {++num3;}   
              je   addnum3   
          addnum1:   
              add   num1,1   
              ret   
          addnum2:   
              add   num2,1   
              ret   
          addnum3:   
              add   num3,1   
              ret   
      move   endp               ;}   
    
    
      printstats   proc   near     ;本子程序作用在上文调用处已经标明。   
          mov   ah,2   
          mov   dl,0ah   
          int   21h   
          mov   dl,0dh   
          int   21h   
          mov   dl,'n'   
          int   21h   
          mov   dl,'='   
          int   21h   
          mov   ch,n   
          call   outputch   
          mov   dl,'   '   
          int   21h   
          mov   dl,'a'   
          int   21h   
          mov   dl,'b'   
          int   21h   
          mov   dl,'c'   
          int   21h   
          mov   dl,'='   
          int   21h   
          mov   ch,num1   
          call   outputch   
          mov   dl,','   
          int   21h   
          mov   ch,num2   
          call   outputch   
          mov   dl,','   
          int   21h   
          mov   ch,num3   
          call   outputch   
          ret   
      printstats   endp       
    
    
      outputch   proc   near         ;本子程序是用来以十进制形式,   
              push   ax                       ;输出ch中的数。   
              mov   ah,0   
              mov   al,ch                   ;将ch赋予al(实际上是ax)待除。   
              mov   bl,10   
              div   bl                         ;ax除以10,此时商(十位)在al中,   
              push   ax                       ;余数(个位)在ah中。先保存一下ax。   
              mov   ah,2   
              cmp   al,0                     ;如果商为0(只有个位),直接输出。   
              je   popax   
              mov   dl,al                   ;否则,先输出商,然后   
              add   dl,30h   
              int   21h   
          popax:   
              pop   ax   
              mov   dl,ah                   ;再输出余数。   
              add   dl,30h   
              mov   ah,2   
              int   21h           
          pop   ax   
          ret   
      outputch   endp   
  code   ends   
      end   main 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -