AVR.5 PUSH,POP和堆疊(STACK)
PUSH和POP
程式設計者有時會覺得32個一般用途暫存器似乎不夠使用, 例如: SBCI, SUBI, CPI, ANDI, ORI和LDI, 只限R16~R31使用;或R26 ~ R31拿來做為間接位址指標的暫存器; 使用指令PUSH, POP將資料存取到SRAM, 就是一種變通的方法
PUSH Rd是將Rd的資料, 複製一份, 存放到SRAM裡,而Rd可以另外繼續使用; 等到需要恢復原來暫存器狀態的時候, 再使用指令POP Rd, 從SRAM取出, 例如:
PUSH R14 ;將R14備份,存放到SRAM裡
PUSH R15 ;將R15備份,存放到SRAM裡
...
INC R14 ;
ADD R15,R14 ;
...
POP R15 ;將原來的R15從SRAM取出
POP R14 ;將原來的R14從SRAM取出
堆疊(STACK)
PUSH把資料一層一層的存放到SRAM, POP再把資料一層一層的從SRAM取出, 這種狀態, 稱之為堆疊 (STACK)
堆疊的方式--先進後出 (First In Last Out)
SRAM的堆疊, 就好像是一個裝有彈簧的魔術箱, 首先將R16的複製, 放進魔術箱, 再將R17的複製放進去, 最後將R18的複製放入(R16,R17,R18另外繼續使用); 當我們要使用原來的R16, R17, R18時,就把魔術箱打開來--第一個彈出來的是R18, 第二個彈出來的是R17, 最後一個彈出來的是R16
這就是堆疊的方式 : 先進後出
PUSH R16
PUSH R17
PUSH R18
...
...
POP R18
POP R17
POP R16
堆疊指標SP (Stack Pointer)
堆疊指標SP位於I/O暫存器中, 它是由SPH和SPL所組成的一個16 bit的暫存器, 所在的位址是$3E (SPH), $3D (SPL)
|
位元 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
$3E($5E) SPH |
SP15 |
SP14 |
SP13 |
SP12 |
SP11 |
SP10 |
SP9 |
SP8 |
|
$3D($5D) SPL |
SP7 |
SP6 |
SP5 |
SP4 |
SP3 |
SP2 |
SP1 |
SP0 |
Read/Write |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
|
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
R/W |
|
|
初始值 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
程式設計者在堆疊之前, 必須先設定SP的起始位址, 因為SRAM的初始值是 $0060, 且由於堆疊是先進後出, 所以SP至少設定在 $0060之後; 例如 :
LDI R16,$01 ;
LD SPH,R16 ;設定SPH的位址為$01
LDI R16,$5F ;
LD SPL,R16 ;設定SPL的位址為$5F
.....
PUSH R7 ;將R7的備份,放到SRAM $015F的位址(SP-1)
PUSH R12 ;將R12的備份,放到SRAM $015E的位址(SP-1)
.....
POP R12 ;將R12從SRAM取出(SP+1)
POP R7 ;將R7從SRAM取出(SP+1)
