3-1 指令格式 標記運算碼運算元註解 標記 1. 標記前不可有空白, 否則會被視為運算碼 2. 標記代表一個 16 位元的記憶體實際位址 3. 標記名稱最多 32 個字元 ( 視組譯器不同而有所不同 ) 4. 標記有大小寫之分 5. 標記可有可無 運算碼 1. 運算碼與標記名稱間, 至少必須空一格, 如果沒有標記名稱, 則運算碼前最少要空一格, 否則會被視為標記 2. 運算碼大小寫相同 3. 可以是 MCS-51 指令或是組譯器假指令 運算元 1. 運算元與運算元之間, 必須以逗號, 隔開 2. 視定址法之不同而有差異, 有些指令有運算元, 有些則無 註解 1. 註解前面要加分號 ;, 組譯器不處理分號之後的文字或指令 2. 註解可有可無, 主要是增加程式的可讀性 2
3-2 定址模式 立即定址法 1. 運算元為一常數資料, 常數可以是 2 進制 10 進制或 16 進制的資料, 在常 數資料前必須加 # 符號 2. 範例 : 將常數資料 15 存入 A 累加器中 MOV A,#00001111B ;2 進制資料 MOV A,#15 ;10 進制資料 MOV A,#0FH ;16 進制資料 直接定址法 1. 運算元為一個 8 位元的位址 2. 只有內部資料記憶體 RAM ( 位址 00H~7FH) 及特殊功能暫存器 SFR ( 位址 80H~FFH) 才能使用 3. 範例 : 將 SFR 中位址 90H (P1) 內的資料存入 A 累加器 MOV A,90H ; 讀取 P1 資料至累加器 A 中 MOV A,P1 ; 讀取 P1 資料至累加器 A 中 暫存器定址 1. 運算元為一暫存器, 如 A 累加器, 暫存器 B,8 位元暫存器 R0~R7,DPH, DPL 等,16 位暫存器 DPTR, 及 PSW 暫存器中的進位旗標 C ( 位元定址 ) 2. 範例 : 將暫存器 R0 內的資料存入 A 累加器 MOV A,R0 ; 將暫存器 R0 內的資料存入 A 中 3
3-2 定址模式 暫存器間接定址 1. 只能使用 R0 R1 或 DPTR 暫存器, 且暫存器之前要加上 @ 符號 2.8 位元暫存器 R0 R1 可定址 00H~FFH 共 256 個位元組的記憶體空間, 而 16 位元暫存器 DPTR 可定址 0000H~FFFFH 共 65536 個空間 3. 範例 : 將資料記憶體位址 80H 內的資料存入 A 累加器 MOV R0,#80H ;R0 指向記憶體位址 80H MOV A,@R0 ; 將位址 80H 內含值存入 A 中 索引定址法 1. 以程式計數器 PC 或 DPTR 暫存器的內容加上 A 累加器之值, 即可定址 65536 (64K) 個記憶體位址 2. 索引定址法適合使用於查表或提取程式記憶體內容 3. 範例 : MOVC A,@A+PC ; 讀取 A+PC 所指位址內容至 A 中 MOVC A,@A+DPTR ; 讀取 A+DPTR 所指位址內容至 A 4
3-3 指令集 MCS-51 指令集共包含 111 個指令, 其中有 49 個 1 位元組指令,45 個 2 位元組指令及 17 個 3 位元組指令 依指令功能可將其分成 5 類, 即 : 資料轉 移指令 算術運算指令 邏輯運算指令 布林運算指令及程式分支指令 指令表符號定義 符號 說明 Rn 所選擇暫存器庫中之 R0~R7,n=0~7 direct 直接定址位址 @Ri 間接定址位址,i=0 或 1 #data 8 位元資料常數 #data16 16 位元資料常數 addr11 11 位元位址常數, 使用於 ACALL 及 AJMP 指令 addr16 16 位元位址常數, 使用於 LCALL 及 LJMP 指令 rel 8 位元偏移位址常數, 使用於 SJMP 及相對跳躍指令中 bit 位元定址位址 以右方資料取代左方資料 (X) 將 X 內容取出 ((X)) 以 X 內容為位址, 以間接定址方式取出資料 rrr n 之 2 進制值 如 n=6,rrr=110 表 3-1 符號定義 5
3-1 3-3 指令集 影響旗標的指令 指令進位旗標 C 溢位旗標 OV 輔助進位 AC ADD ADDC SUBB MUL 0 DIV 0 DA RRC RLC SETB C 1 CLR C 0 CPL C ANL C,bit ANL C,/bit ORL C,bit ANL C,/bit MOV C,bit CJNE 表 3-2 影響旗標的指令 註 : 表示將會影響旗標, 其結果可能是 0 或 1 在 PSW 暫存器中的各旗標位元, 除了同位旗標 P 之外, 其餘皆可以指令設定或清除 6
3-3 指令集 7
3-3 指令集 資料轉移指令 指令說明位元組 機械週期 MOV A,Rn 將暫存器內容移入 A 累加器 1 1 MOV A,direct 將直接位址內容移入 A 累加器 2 1 MOV A,@Ri 暫存器間接定址內容移入 A 累加器 1 1 MOV A,#data 將 8 位元常數資料移入 A 累加器 2 1 MOV Rn,A 將 A 累加器內容移入暫存器 1 1 MOV Rn,direct 將直接位址內容移入暫存器 2 2 MOV Rn,#data 將 8 位元常數資料移入暫存器 2 1 MOV direct,a 將 A 累加器內容移入直接位址內 2 1 MOV direct,rn 將暫存器內容移入直接位址內 2 2 MOV direct,direct 將直接位址內容移入直接位址內 3 2 MOV direct,@ri 間接定址內容移入直接位址內 2 2 MOV direct,#data 將 8 位元常數資料移入直接位址內 3 2 MOV @Ri,A 將 A 累加器內容移入間接位址內 1 1 MOV @Ri,direct 將直接位址內容移入間接位址內 2 2 MOV @Ri,#data 將 8 位元常數資料移入間接位址內 2 1 MOV DPTR,#data16 將 16 位元常數資料移入資料指標內 3 2 MOVC A,@A+DPTR 將程式記憶體內容移入 A 累加器內 1 2 MOVC A,@A+PC 將程式記憶體內容移入 A 累加器內 1 2 MOVX A,@Ri 外部資料記憶體內容移入 A 累加器 1 2 MOVX A,@DPTR 外部資料記憶體內容移入 A 累加器 1 2 MOVX @Ri,A A 累加器內容移入外部資料記憶體 1 2 MOVX @DPTR,A A 累加器內容移入外部資料記憶體 1 2 PUSH direct 將直接位址內容存入堆疊內 2 2 POP direct 自堆疊頂端取出資料至直接位址內 2 2 XCH A,Rn A 累加器內容與暫存器內容互換 1 1 XCH A,direct A 累加器內容與直接位址內容互換 2 1 XCH A,@Ri A 累加器內容與間接位址內容互換 1 1 XCHD A,@Ri A 與間接位址低 4 位元內容互換 1 1 表 3-3 資料轉移指令 8
3-3 指令集 算術運算指令 指令說明位元組機械週期 ADD A,Rn 將暫存器內容加入 A 累加器 1 1 ADD A,direct 將直接位址內容加入 A 累加器 2 1 ADD A,@Ri 將間接位址內容加入 A 累加器 1 1 ADD A,#data 將 8 位元常數資料加入 A 累加器 2 1 ADDC A,Rn 將暫存器與進位 C F 加入 A 累加器 1 1 ADDC A,direct 直接位址內容與進位 C F 加入累加器 2 1 ADDC A,@Ri 間接位址內容與進位 C F 加入累加器 1 1 ADDC A,#data 將 8 位元常數資料與進位加入累加器 2 1 SUBB A,Rn A 累加器內容減暫存器與借位 C F 1 1 SUBB A,direct A 累加器內容減直接位址內容與借位 2 1 SUBB A,@Ri A 累加器內容減間接位址內容與借位 1 1 SUBB A,#data 累加器內容減 8 位元常數資料與借位 2 1 INC A A 累加器內容加 1 1 1 INC Rn 暫存器內容加 1 1 1 INC direct 直接位址內容加 1 2 1 INC @Ri 間接位址內容加 1 1 1 INC DPTR 資料指標 DPTR 內容加 1 1 2 DEC A A 累加器內容減 1 1 1 DEC Rn 暫存器內容減 1 1 1 DEC direct 直接位址內容減 1 2 1 DEC @Ri 間接位址內容減 1 1 1 MUL AB A 累加器乘以暫存器 B, 相乘結果之高 8 位元存入 B, 低 8 位元存入 A 1 4 DIV AB A 累加器除以暫存器 B, 相除結果之商存入 A, 餘數存入 B 1 4 DA A A 累加器內容調整成 10 進制 BCD 數 1 1 表 3-4 算術運算指令 9
3-3 指令集 邏輯運算指令 指令說明位元組機械週期 ANL A,Rn 暫存器 AND 至 A 累加器內 1 1 ANL A,direct 直接位址內容 AND 至 A 累加器內 2 1 ANL A,@Ri 間接位址內容 AND 至 A 累加器內 1 1 ANL A,#data 8 位元資料 AND 至 A 累加器內 2 1 ANL direct,a A 累加器內容 AND 至直接位址內 2 1 ANL direct,#data 8 位元資料 AND 至直接位址內 3 2 ORL A,Rn 暫存器 OR 至 A 累加器內 1 1 ORL A,direct 直接位址內容 OR 至 A 累加器內 2 1 ORL A,@Ri 間接位址內容 OR 至 A 累加器內 1 1 ORL A,#data 8 位元資料 OR 至 A 累加器內 2 1 ORL direct,a A 累加器內容 OR 至直接位址內 2 1 ORL direct,#data 8 位元資料 OR 至直接位址內 3 2 XRL A,Rn 暫存器 XOR 至 A 累加器內 1 1 XRL A,direct 直接位址內容 XOR 至 A 累加器內 2 1 XRL A,@Ri 間接位址內容 XOR 至 A 累加器內 1 1 XRL A,#data 8 位元資料 XOR 至 A 累加器內 2 1 XRL direct,a A 累加器內容 XOR 至直接位址內 2 1 XRL direct,#data 8 位元資料 XOR 至直接位址內 3 2 CLR A 清除 A 累加器 1 1 CPL A A 累加器內容取補數 1 1 RL A A 累加器內容向左旋轉 1 位元 1 1 RLC A A 累加器與進位 C F 一起左旋 1 位元 1 1 RR A A 累加器內容向右旋轉 1 位元 1 1 RRC A A 累加器與進位 C F 一起右旋 1 位元 1 1 SWAP A A 累加器的高低 4 位元互相交換 1 1 表 3-5 邏輯運算指令 10
3-3 指令集 布林運算指令 指令說明位元組機械週期 CLR C 清除進位旗標 C F =0 1 1 CLR bit 清除位元位址內容 2 1 SETBC 設定進位旗標 C F =1 1 1 SETB bit 設定位元位址內容 2 1 CPL C 將進位旗標 C F 內容取補數 1 1 CPL bit 將位元位址內容取補數 2 1 ANL C,bit 將位元位址內容 AND 至 C F 內 2 1 ANL C,/bit 將位元位址內容取補數 AND 至 C F 內 2 2 ORL C,bit 將位元位址內容 OR 至 C F 內 2 2 ORL C,/bit 將位元位址內容取補數 OR 至 C F 內 2 2 MOV C,bit 將位元位址內容移入進位旗標 C F 內 2 1 MOV bit,c 將進位旗標 C F 移入位元位址內 2 2 JC rel 若 C F =1, 則跳至相對位址 rel 2 2 JNC rel 若 C F =0, 則跳至相對位址 rel 2 2 JB bit,rel 若 (bit)=1, 則跳至相對位址 rel 3 2 JNB bit,rel 若 (bit)=0, 則跳至相對位址 rel 3 2 JBC bit,rel 若 (bit)=1, 則跳至相對位址 rel, 同時清除位元位址 bit 內容表 3-6 布林運算指令 3 2 11
3-3 指令集 程式分支指令 指令說明位元組機械週期 ACALL addr11 副程式呼叫 ( 可定址 2KB 範圍 ) 2 2 LCALL addr16 副程式呼叫 ( 可定址 64KB 範圍 ) 3 2 RET 自副程式返回主程式 1 2 RETI 自中斷副程式返回主程式 1 2 AJMP addr11 絕對跳躍 (2KB 範圍 ) 3 2 LJMP addr16 遠程跳躍 (64KB 範圍 ) 3 2 SJMP rel 相對跳躍 (-128byte ~ +127byte) 2 2 JMP @A+DPTR 間接跳躍 (64KB 範圍 ) 1 2 JZ rel 若 A=0, 則跳至 rel 位址範圍 -128byte ~ +127byte 2 2 JNZ rel CJNE A,direct, rel CJNE A,#data, rel CJNE Rn,#data, rel CJNE @Ri, #data,rel DJNZ Rn,rel DJNZ direct,rel 若 A 0, 則跳至 rel 位址範圍 -128byte ~ +127byte 若 A 累加器與直接位址內容不相等, 則跳至 rel 位址範圍 -128byte ~ +127byte 若 A data, 則跳至 rel 位址, 範圍 -128byte ~ +127byte 若暫存器內容 data, 則跳至 rel 位址, 範圍 -128byte ~ +127byte 若間接位址內容 data, 則跳至 rel 位址, 範圍 -128byte ~ +127byte 暫存器內容減 1, 若不等於 0, 則跳至 rel 位址直接位址內容減 1, 若不等於 0, 跳至 rel 位址 2 2 3 2 3 2 3 2 3 2 2 2 3 2 NOP 無動作 1 1 表 3-7 程式分支指令 12
3-5 假指令 所謂假指令 (Pseudo Instruction) 是指組譯程式所提供的指令, 並不是前一節所 提的組合語言指令, 因此假指令並不會佔用到記憶體的位址空間, 在程式中使用 假指令的目的, 是為了使程式在撰寫時更為方便而有效率 假指令 ORG EQU END DB DW LONG REG VAR 語法說明 ORG 表示程式的起始位址, 程式經過組譯後是由 ORG 所指的位址開始存放機器碼 指定 EQU 後面的數值給 EQU 前面的標記 例如敘述 : VAR1 EQU 50H 即是 VAR1=50H 之意 程式結束時要加 END 假指令, 表示組譯到此結束 定義一個位元組 (byte) 的資料給某記憶體位址 DB 是 Define Byte 的縮寫 例如敘述 :VAR1 DB 12H 定義一個字元組即兩個位元組資料 (16bits) 給某記億體位址 DW 是 Define Word 的縮寫 例如敘述 :VAR1 DW 1234H 定義四個位元組 (32bits) 的資料給某一記憶體位址 例如敘述 : VAR1 LONG 12345678H 由使用者自己來定義暫存器 例如敘述 LED REG P1.0 指定 VAR 後面的數值給 VAR 前面的變數, 但與 EQU 不同的是 :EQU 所指定的數值不能改變, 而 VAR 所指定的數值可以隨時改變 表 3-8 2500 A.D. X8051 組譯器常使用的假指令 13
3-5 假指令 數制系統 符號 範例 二進制 (binary) B 01100100B 八進制 (octal) O 或 Q 244O 或 244Q 十進制 (decimal) D 或不指定 100D 或 100 十六進制 (hexdecimal) H 64H 字元 (char) 單引號或雙引號 A 字串 (string) 單引號或雙引號 I Love 8051 表 3-9 2500 A.D. X8051 組譯器的數制系統 組譯運算 符號 範例 加法 + 指令 :MOV R0,#(20+10) 結果 :R0 內容值為 30 減法 - 指令 :MOV R1,#(20-10) 結果 :R1 內容值為 10 乘法 * 指令 :MOV R2,#(20*10) 結果 :R2 內容值為 200 除法 / 指令 :MOV R3,#(20/10) 結果 :R3 內容值為 2 取高位元組資料 > 指令 :MOV TH0,#>1234H 結果 :TH0 內容值為 12H 取低位元組資料 < 指令 :MOV TL0,#<1234H 結果 :TL0 內容值為 34H 代表程式計數器的值 $ 指令 :JMP $ 結果 : 重覆執行同一行指令即 JMP $ 表 3-9 2500 A.D. X8051 組譯器的運算 14