AVR單片機(jī)指令系統(tǒng)是RISC結(jié)構(gòu)的精簡指令集,CISC結(jié)構(gòu)存在指令系統(tǒng)不等長,指令數(shù)多,CPU利用效率低,執(zhí)行速度慢等缺陷。
ATmega16共有131條指令,按功能可分為五大類,它們是:
A.算術(shù)和邏輯運(yùn)算指令(28 條);
B.比較和跳轉(zhuǎn)指令(36 條);
C.數(shù)據(jù)傳送指令(35 條);
D.位操作和位測試指令(28 條);
E.MCU控制指令(4 條)。
AVR一條指令的長度大多數(shù)為16位,還有少部分為32位。
AVR的指令的一般格式為:

操作碼用于指示CPU執(zhí)行何種操作,是加法還是減法,是數(shù)據(jù)傳送還是數(shù)據(jù)移位。
一條指令可以只有操作碼,或第一操作數(shù)。
AVR的匯編語句的格式:
(1) [標(biāo)號:] 偽指令 [操作數(shù)] [;注釋]
(2) [標(biāo)號:] 指令 [操作數(shù)] [;注釋]
1.AVR指令的尋址方式和尋址空間
指令的一個重要組成部分是操作數(shù)。指令給出參與運(yùn)算數(shù)據(jù)的方式稱為尋址方式。CPU執(zhí)行指令時,首先要根據(jù)地址獲取參加操作的操作數(shù),然后才能對操作數(shù)進(jìn)行操作,操作的結(jié)果還要根據(jù)地址保存在相應(yīng)的儲存器或寄存器中。
下面介紹部分AVR的部分指令及尋址方式:
(1)單寄存器尋址 例:INC Rd ;操作:Rd←Rd+1
INC R5 ;將寄存器R5內(nèi)容加1回放。
(2)雙寄存器尋址 例:ADD Rd, Rr ;操作:Rd←Rd+Rr
ADD R0, R1 ;將R0和R1寄存器內(nèi)容相加,結(jié)果回放R0。
(3)I/O寄存器直接尋址 例:IN Rd, P ;操作:Rd←P。
IN R5, $3E ;讀 I/O 空間地址為$3E寄存器(SPH)的內(nèi)容,放入寄存器R5。
(4)數(shù)據(jù)存儲器空間直接尋址 例:LDS Rd, K ;操作:Rd←(K)
LDS R18, $100 ;讀地址為$100的SRAM中內(nèi)容,傳送到R18中。
(5)數(shù)據(jù)存儲器空間的寄存器間接尋址 例:LD Rd, Y ;操作:Rd←(Y),把以Y為指針的SRAM的內(nèi)容送Rd。
LD R16, Y ;設(shè)Y=$0567,即把SRAM地址為$0567的內(nèi)容傳送到R16中。
(6)程序存儲器空間取常量尋址
例:LPM ;操作:R0←(Z),即把以Z為指針的程序存儲器的內(nèi)容送R0。
若 Z=$0100,即把地址為$0080的程序存儲器的低字節(jié)內(nèi)容送R0。
若 Z=$0101,即把地址為$0080的程序存儲器的高字節(jié)內(nèi)容送R0。
例:LPM R16, Z ;操作:R16←(Z),即把以Z為指針的程序存儲器的內(nèi)容送R16。
若 Z=$0100,即把地址為$0080 的程序存儲器的低字節(jié)內(nèi)容送R16。
若 Z=$0101,即把地址為$0080 的程序存儲器的高字節(jié)內(nèi)容送R16。
(7)程序存儲器空間寫數(shù)據(jù)尋址
例:SPM ;操作:(Z)←R1:R0,把 R1:R0 內(nèi)容寫入以 Z 為指針的程序存儲器單元。
(8)程序存儲器空間直接尋址
例:JMP $0100 ;操作:PC←$0100。程序計數(shù)器 PC 的值設(shè)置為$0100,接下來執(zhí)行程序存儲器$0100 單元的指令代碼。
例:CALL $0100 ;操作:STACK←PC+2; SP← SP-2; PC←$0100。先將程序計數(shù)器 PC 的當(dāng)前值加 2 后壓進(jìn)堆棧(CALL 指令為 2 個字長),堆棧指針計數(shù)器 SP 內(nèi)容減 2,然后 PC 的值為$0100,接下來執(zhí)行程序存儲器$0100 單元的指令代碼。
(9)程序存儲器空間相對尋址
例:RJMP $0100 ;操作:PC←PC+1+$0100。若當(dāng)前指令地址為$0200(PC=$0200),即把$0301 送程序計數(shù)器 PC,接下來執(zhí)行程序存儲器$0301 單元的指令代碼。
例:RCALL $0100 ;操作:STACK←PC+1;SP←SP-2;PC←PC+1+$0100。若當(dāng)前指令地址為$0200(PC=$0200),先將程序計數(shù)器 PC 的當(dāng)前值加 1 后壓進(jìn)堆棧,堆棧指針計數(shù)器SP 內(nèi)容減 2,然后 PC 的值為$0301,接下來執(zhí)行程序存儲器$0301 單元的指令代碼。
(10)數(shù)據(jù)存儲器空間堆棧寄存器 SP 間接尋址
例:PUSH R0 ;操作:STACK←R0;SP←SP-1。若當(dāng)前 SP=$10FF,先把寄存器 R0 的內(nèi)容送到 SRAM 的$10FF 單元,再將 SP 內(nèi)容減 1,即 SP=$10FE。
例:POP R1 ;操作:SP←SP+1;R1←STACK。若當(dāng)前 SP=$10FE,先將 SP 內(nèi)容加 1,再把 SRAM 的$10FF 單元內(nèi)容送到寄存器 R1,此時 SP=$10FF。
此外,在 CPU 響應(yīng)中斷和執(zhí)行 CALL 一類的子程序調(diào)用指令(SP = SP-2),以及執(zhí)行中斷返回 IRET 和子程序返回 RET 一類的子程序返回指令中(SP = SP+2),都隱含著使用堆棧寄存器 SP 間接尋址的方式。
2.AVR匯編器偽指令
在匯編語言程序中可以使用一些偽指令。偽指令不屬于 CPU 指令集,編譯時并不產(chǎn)生實際的目標(biāo)機(jī)器操作代碼,只是用于在匯編程序中對地址、寄存器、數(shù)據(jù)、常量等進(jìn)行定義說明,以及對編譯過程進(jìn)行某種控制等。AVR 的指令系統(tǒng)不包括偽指令,偽指令通常由匯編編譯系統(tǒng)給出。

偽指令一般以 . 開頭,如:
.DSEG ;RAM 數(shù)據(jù)段(SRAM) var1: .BYTE 1 ;保留 1 個字節(jié)的存儲單元,用 var1 標(biāo)識 table: .BYTE tab_size ;保留 tab_size 個字節(jié)的存儲空間 .CSEG ;代碼段開始(Flash) ldi r30, low(var1) ;將保留存儲單元 var1 起始地址的低 8 位裝入 Z ldi r31, high(var1) ;將保留存儲單元 var1 起始地址的高 8 位裝入 Z ld r1, Z ;將保留存儲單元的內(nèi)容讀到寄存器 R1