• 汇编语言、与C语言、实现--汉诺塔--


    题意描述:  

       用汇编语言实现汉诺塔。只需要显示移盘次序,不必显示所移盘的大小,例如: X>Z,X>Y,Z>Y,X>Z,....。

    (n阶Hanoi塔问题)假设有三个分别命名为X、Y、Z的塔座,在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:

    1)每次只能移动一个圆盘;

    2)圆盘可以插在X、Y、Z中的任一塔座上;

    3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。

    汉诺塔的实现,用C语言来解释就是函数递归调用实现

    如果转为汇编实现,就直接进入栈进行相应的操作就行(当然你也可以用汇编语言宏实现高级的递归调用..)

    C语言方式:

    void move(char one,char three){    //one 移到thre
    
    printf("%c--->%c",one,three);
    
    }
    
    void HANOI(int n,char one,char two,char three){
    
    if(n==1){                          //如果只有一个圆盘,直接将这个圆盘从one移到three
    
    move(one,three);
    }
    
    else{                                 //如果大于一个圆盘
    
    HANOI(n-1,one,three,two); //首先将n-1个从one经过three移到two上,此时one上剩最大的一个圆盘
    
    move(one,three);               //将最大的圆盘从one移到three上
    
    HANOI(n-1,two,one,three); //之后将n-1个从two经过one移到three上,完成。
    
    }
    
    }               // end of void
    
    HANOI(5,'X','Y','Z');  //即可5阶汉诺塔从X盘移到Z盘
    
     

    递归操作仔细想想就可以了,这样栈的操作逐渐明朗,你就可以用汇编语言实现它了(通过bp栈指针的运算进栈push出栈pop就可以实现相应递归调用)。

    汇编代码实现如下:

      1 DATA    SEGMENT
      2         n db ?
      3         msg db 0dh,0ah,'Enter the number you want : $'
      4         msg1 db 0dh,0ah,'HANOI-MOVE Procedure with : $',0ah,0dh
      5         to db '--->$'
      6         count dw 0   ; 5个一组输出显示
      7 DATA    ENDS
      8 
      9 CODE    SEGMENT
     10         ASSUME CS:CODE,DS:DATA
     11 START: 
     12         MOV     AX,DATA
     13         MOV     DS,AX
     14         
     15         LEA DX,msg
     16         CALL intro
     17 KEYIN:        
     18         MOV AH,01H         ;字符输入并回显
     19         INT 21H
     20         MOV byte ptr[n],Al         ;接收键入的n值
     21         
     22         LEA DX,msg1
     23         CALL intro
     24         MOV DL,0ah
     25         CALL DISPLAY
     26         
     27         MOV AL,byte ptr[n]
     28         SUB AL,30H
     29         CBW
     30         MOV DX,AX
     31         MOV AX,'X'
     32         MOV BX,'Y'
     33         MOV CX,'Z'
     34         ;MOV DX,[n]
     35         
     36         PUSH DX
     37         PUSH CX
     38         PUSH BX
     39         PUSH AX
     40         
     41         CALL HANOI_MOVE
     42         ADD SP,8
     43         
     44         MOV DL,0ah
     45         CALL DISPLAY
     46         LEA DX,msg
     47         CALL intro
     48         JMP KEYIN
     49         
     50 GroupMake:
     51         INC [count]
     52         MOV AX,[count]
     53         MOV BL,5           ;5 个一组
     54         DIV BL
     55         CMP AH,0
     56         JNE SPACE
     57         MOV DL,0ah
     58         CALL DISPLAY        ;输出换行       
     59         JMP CLOSE
     60     SPACE:
     61         MOV DX,20H
     62         CALL DISPLAY        ;输出空格
     63     CLOSE:
     64           RET
     65 
     66 STEP:     ;输出步骤号
     67         MOV AX,[count]  ;防止count多位数不正确输出--hexTOdec
     68         MOV CX,0
     69         MOV BX,10
     70 DISP1:
     71         MOV DX,0
     72         DIV BX
     73         PUSH DX
     74         INC CX
     75         OR AX,AX
     76         JNZ DISP1    
     77         
     78         MOV DL,5BH    ; 输出显示[
     79         CALL DISPLAY            
     80 DISP2:  
     81         POP DX
     82         ADD DL,30H    ; 输出显示对应十进制
     83         CALL DISPLAY    
     84         LOOP DISP2   
     85         
     86         MOV DL,5DH    ; 输出显示]
     87         CALL DISPLAY
     88         RET        
     89         
     90 intro proc near          ;提示语
     91          MOV AH,09H
     92          INT 21H
     93          ret
     94 intro endp
     95      
     96 DISPLAY proc near        ;输出字符
     97         MOV AH,02H
     98         INT 21H
     99         RET
    100 DISPLAY endp
    101       
    102 HANOI_MOVE proc near
    103         MOV BP,SP
    104         MOV AX,[BP+8]
    105         CMP AX,1
    106         JG moreThanOne    ;n 不等于1则跳转
    107         CALL STEP
    108         MOV DX,[BP+2]     ;取第一个值
    109         CALL DISPLAY
    110         LEA DX,to           
    111         CALL intro
    112         MOV DX,[BP+6]     ;取第三个值
    113         CALL DISPLAY    
    114         CALL GroupMake
    115         
    116           RET
    117 
    118 
    119 moreThanOne:
    120         MOV AX,[BP+2]
    121         MOV BX,[BP+4]
    122         MOV CX,[BP+6]
    123         MOV DX,[BP+8]
    124         DEC DX              ;n-1
    125         PUSH DX
    126         PUSH BX
    127         PUSH CX
    128         PUSH AX
    129         CALL HANOI_MOVE      ;递归一次,进行下一循环
    130         ADD SP,8
    131         
    132         MOV BP,SP
    133         CALL STEP
    134         MOV DX,[BP+2]     ;取第一个值
    135         CALL DISPLAY
    136         LEA DX,to           
    137         CALL intro
    138         MOV DX,[BP+6]     ;取第三个值
    139         CALL DISPLAY    
    140         CALL GroupMake
    141         
    142         MOV AX,[BP+2]
    143         MOV BX,[BP+4]
    144         MOV CX,[BP+6]
    145         MOV DX,[BP+8]  
    146         DEC DX              ;n-1
    147         PUSH DX
    148         PUSH CX
    149         PUSH AX
    150         PUSH BX
    151         CALL HANOI_MOVE      ;递归一次,进行下一循环
    152         ADD SP,8
    153         
    154         RET
    155 HANOI_MOVE endp
    156 
    157 EXIT:   MOV     AH,4CH      ;退出系统
    158         INT    21H 
    159 CODE    ENDS
    160         END START

    耐心看看就行了,不是很难,栈的第一个参数是从bp+2开始的,别搞错了。
    此为MASM语言格式汇编程序,链接成功后生成相应exe文件,打开即有如下执行效果..

    ============================此为原创文章,转载请注明。谢谢。======================================

  • 相关阅读:
    linux利用grep查看打印匹配的下几行或前后几行的命令
    Linux NetHogs监控工具介绍
    db2 查看进程 db2中的常用命令及使用方法
    Linux python <tab>自动补全
    Saltstack pillar组件
    History(历史)命令用法
    Saltstack grains组件
    Saltstack常用模块及API
    文本处理三剑客之AWK的用法
    linux程序调试命令strace
  • 原文地址:https://www.cnblogs.com/imwtr/p/4105160.html
Copyright © 2020-2023  润新知