堆栈操作的进一步探讨

如果参与的寄存器比较多,这种PUSHPOP岂不是又臭又长?放心,PUSH/POP指令足够体贴,支持一次操作多个寄存器。像这样:

PUSH {R0-R2} ;压入R0-R2

PUSH {R3-R5,R8, R12} ;压入R3-R5,R8,以及R12

POP时,可以如下操作:

POP {R3-R5,R8, R12} ;弹出R3-R5R8,以及R12

POP {R0-R2} ;弹出R0-R2

注意:在寄存器列表中,不管寄存器的序号是以什么顺序给出的,汇编器都将把它们升序排序。然后先push序号大的寄存器,所以也就先pop序号小的寄存器。(这是译者在实验中发现的)。如果不按升序写寄存器,也许有些汇编器会给出语法错误。

PUSH/POP对子还有这样一种特殊形式,形如

PUSH {R0-R3, LR}

POP {R0-R3, PC}

请注意:POP的最后一个寄存器是PC,并不是先前PUSHLR。这其实是一个返回的小技巧。与其按部就班地把先前LR的值弹回LR,再复制给PC来返回;不如干脆绕过LR,直接传给PC !那不怕LR的值没有被恢复吗?不怕,因为LR在子程序调用中的唯一用处,就是在返回时提供返回地址。因此,在返回后,先前保存的返回地址就没有利用价值了,所以只要PC得到了正确的值,不恢复也没关系。

PUSH指令等效于与使用R13作为地址指针的STMDB指令,而POP指令则等效于使用R13作为地址指针的LDMIA指令——STMDB/LDMIA还可以使用其它寄存器作为地址指针。

你可能感兴趣的:(堆栈操作的进一步探讨)