Chinaunix首页 | 论坛 | 博客

分类: LINUX

2013-01-03 13:54:01

8051 堆栈操作指令(2条)
    PUSH    direct ;SP <- SP+1, (SP) <- (direct)
    POP     direct ;(SP) -> (direct), SP <- SP-1

    第一条指令称为压栈指令,用于把 direct 为地址的操作数传送到堆栈中去。这条指令执行时分为两步:第一步是先使 SP 的地址加 1,使之指向新的存储单元;第二步是把 direct 中的操作数压入由 SP 指向的存储单元中。第二条指令称为弹栈指令,其功能是把 SP 所指向的存储单元中的内容弹到 direct 单元中。
    注意:8051 的硬件堆栈的生长方向是由下往上!
8051 子程序调用和返回指令
    短调用指令:ACALL    addr11 ;PC <- PC+2
                                ;SP <- SP+1, (SP) <- PC7 - PC0
                                ;SP <- SP+1, (SP) <- PC15 - PC8
                                ;PC10 - PC0 <- addr11

    长调用指令:LCALL    addr16 ;PC <- PC+3
                                ;
SP <- SP+1, (SP) <- PC7 - PC0
                                ;SP <- SP+1, (SP) <- PC15 - PC8
                                ;PC <- addr16

    无论是短调用指令还是长调用指令,都有一个压栈的过程,这是调用该指令后硬件自动完成的。
    返回指令:
    RET ;PC15 - PC8 <- (SP), SP <- SP-1
        ;PC7 - PC0 <- (SP), SP <- SP-1
   
RETI ;PC15 - PC8 <- (SP), SP <- SP-1
         ;PC7 - PC0 <- (SP), SP <- SP-1

    这两条指令的功能完全相同,都是把堆栈中的断点地址恢复到程序计数器 PC 中,从而使单片机回到断点地址处执行程序。RET 称为子程序返回指令,只能用在子程序末尾。RETI 称为中断返回指令,只能用在中断服务程序末尾。机器执行 RETI 指令后除返回程序断点地址处执行外,还将清除相应中断优先级状态位,以允许单片机响应低优先级中断请求。
   
    KEIL C 编译器在子函数调用过程中,参数的传递默认是采用寄存器,当寄存器无法满足要求时,额外的参数由存储器传递,而并不通过堆栈 SP。这也是为什么 KEIL C 中的函数默认情况下是不可重入的。

扩展:ARM程序参数传递规则
    如果参数小于 4 个,使用寄存器 R0-R3 来传递;如果参数的个数超过 4 个,就必须用堆栈来传递。

                       ——忠于梦想 勇于实践    linux_xpj@opencores.org
 
阅读(3677) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~