AVR.4 資料移轉指令(Data Ransfer Instructions)
資料移轉指令大致上可分為下列4種類型 :
1. 暫存器和暫存器 (或常數) 之間, 資料的移轉 : MOV, LDI
2. 暫存器和X,Y,Z暫存器所指的位址之間,資料的移轉 : LD,ST,LPM
3. 暫存器和PORT之間, 資料的移轉 : IN, OUT
4. 暫存器和SRAM之間, 資料的移轉 : PUSH, POP (在6-5節說明)
指令集的符號 :
X : 由R27:R26組合而成16-bit的指標暫存器
Y : 由R29:R28組合而成的指標暫存器
Z : 由R31:R30組合而成的指標暫存器
P : I/O暫存器的PORT
K : 常數或byte的資料 (8 bit)
|
資料移轉指令 (Data Transfer Intructions) |
||||
|
|
運算元 |
運算 |
說明 |
Flag Clock |
|
MOV |
Rd, Rr |
PC <- PC + 1 Rd <- Rr |
把Rr的資料複製一份,移轉到Rd Copy Register |
None 1 |
|
LDI |
Rd, K |
PC <- PC + 1 Rd <- K |
把常數(K)移轉到Rd,這時Rd = K Load Immediate |
None 1 |
|
LD |
Rd, X |
PC <- PC + 1 Rd <- (X) |
X所指的位址的資料,複製一份,移轉到Rd Load Indirect |
None 2 |
|
LD |
Rd, X+ |
PC <- PC + 1 Rd <- (X), X <- X+1 |
X所指的位址的資料,複製一份,移轉到Rd;然後X + 1 Load Indirect and Post-Increment |
None 2 |
|
LD |
Rd, -X |
PC <- PC + 1 X <- X - 1 Rd <- (X) |
X所指的位址先減1,再把這個位址的資料,複製一份,移轉到Rd Load Indirect and Pre-Decrement |
None 2 |
|
LD |
Rd, Y |
PC <- PC + 1 Rd <- (Y) |
Y所指的位址的資料,複製一份,移轉到Rd Load Indirect |
None 2 |
|
LD |
Rd, Y+ |
PC <- PC + 1 Rd <- (Y), Y <- Y +1 |
Y所指的位址的資料,複製一份,移轉到Rd;然後Y + 1 Load Indirect and Post-Increment |
None 2 |
|
LD |
Rd, -Y |
PC <- PC + 1 Y <- Y-1 Rd <- (Y) |
Y所指的位址先減1,再把這個位址的資料,複製一份,移轉到Rd Load Indirect and Pre-Decrement |
None 2 |
|
LDD |
Rd, Y+q |
PC <- PC + 1 Rd <- (Y+q) |
Y+q所指的位址的資料,複製一份,移轉到Rd Load Indirect and Displacement |
None 2 |
|
LD |
Rd, Z |
PC <- PC + 1 Rd <- Z |
Z所指的位址的資料, 複製一份,移轉到Rd Load Indirect |
None 2 |
|
LD |
Rd, Z+ |
PC <- PC + 1 Rd <- (Z), Z <- Z +1 |
Z所指的位址的資料,複製一份,移轉到Rd; 然後Z+1 Load Indirect and Post-Increment |
None 2 |
|
LD |
Rd, -Z |
PC <- PC + 1 Z <- Z-1 Rd <- (Z) |
Z所指的位址的先減1,再把這個位址的資料,複製一份,移轉到Rd Load Indirect and Pre-Decrement |
None 2 |
|
LDD |
Rd, Z+q |
PC <- PC + 1 Rd <- (Z+q) |
Z+q所指的位址的資料,複製一份,移轉到Rd Load Indirect and Displacement |
None 2 |
|
ST |
X, Rr |
PC <- PC + 1 (X) <- Rr |
Rr的資料,複製一份,移轉到X所指的位址 Store Indirect |
None 2 |
|
ST |
X+, Rr |
PC <- PC + 1 (X) <- Rr, X <- X +1 |
Rr的資料,複製一份,移轉到X所指的位址,;然後X+1 Store Indirect and Post-Increment |
None 2 |
|
ST |
-X, Rr |
PC <- PC + 1 X-1 <- X (X) <- Rr |
X所指的位址先減1,再把Rr的資料,複製一份,移轉到X所指的位址 Store Indirect and Pre-Decrement |
None 2 |
|
ST |
Y, Rr |
PC <- PC + 1 (Y) <- Rr |
Rr的資料,複製一份,移轉到Y所指的位址 Store Indirect |
None 2 |
|
ST |
Y+, Rr |
PC <- PC + 1 (Y) <- Rr, Y <- Y +1 |
Rr的資料,複製一份,移轉到Y所指的位址,然後Y+1 Store Indirect and Post-Increment |
None 2 |
|
ST |
-Y, Rr |
PC <- PC + 1 Y-1 <- Y (Y) <- Rr |
Y所指的位址先減1,再把Rr的資料,複製一份,移轉到Y所指的位址 Store Indirect and Pre-Decrement |
None 2 |
|
STD |
Y+q, Rr |
PC <- PC + 1 (Y+q) <- Rr |
Rr的資料,複製一份,移轉到Y+q所指的位址 Store Indirect and Displacement |
None 2 |
|
ST |
Z, Rr |
PC <- PC + 1 (Z) <- Rr |
Rr的資料,複製一份,移轉到Z所指的位址 Store Indirect |
None 2 |
|
ST |
Z+, Rr |
PC <- PC + 1 (Z) <- Rr, Z <- Z +1 |
Rr的資料,複製一份,移轉到Z所指的位址,然後Z+1 Store Indirect and Post-Increment |
None 2 |
|
ST |
-Z, Rr |
PC <- PC + 1 Z-1 <- Z (Z) <- Rr |
Z所指的位址先減1,再把Rr的資料,複製一份,移轉到Z所指的位址 Store Indirect and Pre-Decrement |
None 2 |
|
STD |
Z+q, Rr |
PC <- PC + 1 (Z+q) <- Rr |
Rr的資料,複製一份,移轉到Z+q所指的位址 Store Indirect and Displacement |
None 2 |
|
LPM |
|
PC <- PC + 1 R0 <- (Z) |
Z所指的位址的資料,移轉到R0 Load Program Memory |
None 3 |
|
LDS |
Rd, K |
PC <- PC + 2 Rd <- K |
K所指的位址的資料,移轉到Rd Load Direct from SRAM |
None 3 |
|
STS |
K, Rr |
PC <- PC + 2 K <- Rr |
Rr的資料移轉到K所指的位址 Store Direct to SRAM |
None 3 |
|
IN |
Rd, P |
PC <- PC + 1 Rd <- P |
Port的資料移轉到Rd In Port |
None 1 |
|
OUT |
P, Rr |
PC <- PC + 1 P <- Rr |
Rr的資料移轉到PORT Out Port |
None 1 |
|
PUSH |
Rd |
PC <- PC + 1 STACK <- Rd SP <- SP - 1 |
Rd的資料複製一份,放進SRAM Push Register on Stack |
None 2 |
|
POP |
Rd |
PC <- PC + 1 Rd <- STACK SP <- SP + 1 |
從SRAM取出Rd Pop Register from Stack |
None 2 |
指令的說明
1. MOV Rd,Rr 是把Rr的資料複製一份, 移轉到Rd, 而Rd原本的資料消失, 變成和Rr的資料相同; LDI Rd,K是把常數K移轉到Rd, 所以這個指令只限於R16 ~ R31使用, 不論Rd之前是多少, 這時Rd=K, 我們時常使用LDI來直接指定暫存器的資料內容, 例如 :
LDI R16,$25 ;這時R16=$25
LDI R20,$32 ;這時R20=$32
2. X,Y,Z暫存器是一個間接位址的指標暫存器 (indirect address pointer register ), 可以指向資料記憶體從 $000~ $015F的位址; 使用的方式如下 :
LDI R26,$09 ;將常數$09載入R26
LDI R27,$00 ;將常數$00載入R27
LD R1,X ;X指向$0009的位址 (即R9)
將X所指的位址$0009的資料,複製一份,移轉到R16
3. LD Rd,X+是將X所指的位址的資料,複製一份, 移轉到Rd, 然後X+1, 指向下一個位址; 所以X+是有累加性的, X會一直加1, 指向下一個位址 (Y+和Z+亦同) 例如 :
LDI R27,$10 ;設定XH為$10
LDI R26,$20 ;設定XL為$20
LD R0,X+ ;將X所指的位址$1020的資料,載入R1,接著X+ 1,指向下一個位址$1021
LD R1,X ;將X所指的位址$1021的資料,載入R1
...
4. LD Rd,-X 是將X所指的位址減1, 然後將這個位址的資料, 複製一份, 移轉到Rd ;同樣的, -X也是有累減性的, X所指的位址會一直減1, 指向上一個位址 (-Y和-Z亦同), 例如 :
LDI R27,$00 ;設定XH為$00
LDI R26,$22 ;設定XL為$22, X指向$0022的位址
LD R3,-X ;X-1=$0021, 將位址在$0021的資料, 載入R3
...
5. LDD Rd,Y+q 是將Y所指的位址加q (0~63),然後將這個Y+q所指的位址的資料, 複製一份, 移轉到Rd; 而這種指令是沒有累加或累減的特性,只能指向Y+q (Z+q亦同, 而X沒有這項功能); 例如 :
LDI R29,$13 ;設定YH為$13
LDI R28,$00 ;設定YL為$00,Y指向$1300的位址
LDI R2,Y+2 ;將位址在$1302的資料,載入R3
註 : ST類似LD,就不再列出
6. LPM 是將Z所指的位址的資料, 複製一份, 移轉到R0, 這個指令固定是Z和R0的組合, 所以只要直接寫LPM就可以了, 例如 :
LDI R31
LDI R30,$F0 ;Z指向$00F0的位址
LPM ;將位址在$00F0的資料,載入R0
7. LDS和STS 是直接指向一個16-bit的位址 (從0 ~ 65535), 這個16-bit的位址包括可以指向外部SRAM, 例如 :
LDS R2,$FF00 ;將位址在$FF00的資料,載入R2
STS $DD00,R3 ;將R3的資料,載入位址在$DD00的暫存器
NOTE : 存取外部SRAM前,必須將MCUCR暫存器的bit 7 (SRE) 設定為1
8. IN,OUT是一般用途暫存器與I/O暫存器之間資料的存取, 而I/O暫存器可以以縮寫的英文字母表示, 或是參考檔, 這個檔的內容即是定義一些字; 例如 :
IN R25,$16 ;讀取PORT B
OUT $18,R17 ;寫回PORT B
