51 单片机汇编语言:利用 RET 指令实现多路分支

来源:互联网 发布:office mac版怎么安装 编辑:程序博客网 时间:2024/06/05 10:54

有这样一个问题:


------------------------------


已知程序执行前有 A = 02H,SP = 52H,(51H) = FFH,(52H) = FFH。


执行下列程序:


    POP   DPH

    POP   DPL

    MOV   DPTR, #4000H  

    RL    A

    MOV   B, A

    MOVC  A, @A + DPTR

    PUSH  A

    MOV   A, B

    INC   A

    MOVC  A, @A + DPTR

    PUSH  A

    RET


    ORG   4000H

    DB    10H, 80H, 30H, 50H, 30H, 50H


求程序执行后:


A=(  )H、SP=(  )H、(51H) =(  )H、(52H)=(  )H、PC=(    )H。


------------------------------


这个问题,在百度知道出现过很多次,搜一下,就会出来几十个链接。


但是回答正确的,确实不多。


有的提问者,好像是说,这是什么学校教材上的习题。


在这个程序中,写错了两条指令:


非法指令:PUSH  A

应该写成:PUSH  ACC


做为教材来说,这可是一个 BUG 啊,呵呵



这个程序,是利用 RET 指令来进行多路分支。


程序中,有两条查表指令:MOVC  A, @A + DPTR,


当 A = 0 时,将从 4000H 处,先后读出 10H、80H;

当 A = 1 时,将从 4000H 处,先后读出 30H、50H;

当 A = 2 时,将从 4000H 处,先后读出 30H、50H。


本题目的条件已经给出:A = 02H,那么就是读出了 30H、50H。


读出数据后,先后压栈,再执行 RET。


RET 指令,就是把堆栈中的两个字节,送到 PC。


那么,PC = 5030H,就是这么来的。


全部的空格,填写如下:

A=(50)H、SP=(50)H、(51H) =(30)H、(52H)=(50)H、PC=(5030)H。


------------------------------


本程序,是个子程序结构,应该用 CALL 指令来调用。


在本程序开始处,用 POP 指令,抛弃了 CALL 自动保存的返回地址。


腾出了两个字节的堆栈空间,又压入两字节数据,然后,再返回。


RET 返回指令,就会用刚刚压入两字节数据,当做返回地址。


本程序,是属于偷梁换柱,还是移花接木 ?


------------------------------


下面逐条解释一下:


    POP   DPH

    POP   DPL           ;弹出两次,SP = SP - 2 = 50H


    MOV   DPTR, #4000H  

    RL    A             ;乘以2

    MOV   B, A          ;B = 04H


    MOVC  A, @A + DPTR  ;取出第4个字节30H

    PUSH  ACC           ;SP = SP + 1 = 51H, (51H)=30H


    MOV   A, B

    INC   A             ;A = 05H

    MOVC  A, @A + DPTR  ;取出第5个字节50H

    PUSH  ACC           ;SP = SP + 1 = 52H, (52H)=50H


    RET                 ;子程序返回指令



执行 RET 指令时,是从堆栈中弹出两个字节到 PC 的高、低八位。


即:

(SP) → PCH,然后 SP - 1 → SP;

(SP) → PCL,然后 SP - 1 → SP。


即:

(52H) = 50H → PCH,SP = 51H

(51H) = 30H → PCL,SP = 50H


那么,PC = 5030H,就是这么来的。


------------------------------


进行多路分支,还有简单一点的方法。


如,利用指令:JMP  @A + DPTR,就可以。


那么,前面的程序,可以改为:


    MOV   DPTR, #4000H  

    RL    A

    MOV   B, A

    MOVC  A, @A + DPTR 

    XCH   A, B


    INC   A

    MOVC  A, @A + DPTR ;先后读出两字节


    MOV   DPH, A       ;把读出数据送到 DPTR

    MOV   DPL, B


    CLR   A            ;A=0

    JMP   @A + DPTR    ;以 DPTR 内容为目的地,转移


    ORG   4000H

    DB    10H, 80H, 30H, 50H, 30H, 50H


程序这样写,就不涉及堆栈了,也就没有前一个程序那么复杂的推导。


理解起来,可以轻松些。


这个程序,没有使用 RET 指令,那么,就不要用 CALL 来调用了。


要用 JMP 指令来应用本程序。


------------------------------

题目链接:


http://zhidao.baidu.com/question/62813244.html

http://zhidao.baidu.com/question/508425830.html

http://zhidao.baidu.com/question/586060870.html

http://zhidao.baidu.com/question/205965529.html


------------------------------


0 0
原创粉丝点击