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, 這個指令固定是ZR0的組合, 所以只要直接寫LPM就可以了, 例如 :

 

LDI             R31

 

LDI             R30,$F0           ;Z指向$00F0的位址

 

LPM                               ;將位址在$00F0的資料,載入R0

 

 

 

7.   LDSSTS 是直接指向一個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

 

 

 

 

文章標籤
全站熱搜
創作者介紹
創作者 zeppe 的頭像
zeppe

ZEPPE

zeppe 發表在 痞客邦 留言(0) 人氣(316)