在调用函数时,也即当执行LCALL、ACALL等汇编指令时,硬件首先把PC指针压入到SP指向的系统栈(PC不可寻址,无法用程序出入栈,只能由硬件自动完成),随着函数调用链条不断加长,SP指向的系统栈被占用的空间越来越多。
下面看一下执行ACALL和LCALL时,硬件为我们自动做了什么? (这些信息都能从帮助文件中找到,keil->Help->uVision Help打开帮助文件,依次展开8051 instruction set指令集->Instructions)
ACALL等价于: (下述代码由硬件自动完成) PC = PC + 2 SP = SP + 1 (SP) = PC[7-0] SP = SP + 1 (SP) = PC[15-8] PC[10-0] = A[10-0] |
LCALL等价于: PC = PC + 3 SP = SP + 1 (SP) = PC[7-0] SP = SP + 1 (SP) = PC[15-8] PC = addr16 |
PC存放的是下一条要执行的指令,在调用子函数前,要把紧跟ACALL/LCALL指令后面的一条指令的ROM地址入栈,因为ACALL指令本身占用2字节,LCALL占用3字节,所以上面
的代码才一个PC+2,一个PC+3。
这里顺便再提一下函数(子程序)的返回指令:R