指令系統是計算機硬件的語言系統,也叫機器語言,它是軟件和硬件的主要界面,從系統結構的角度看,它是系統程序員看到的計算機的主要屬性。指令系統表征了計算機的基本功能,決定了機器所要求的能力,也決定了指令的格式和機器的結構。
51系列單片機一般使用匯編語言(Assembly Language)直接編程,其指令系統中,有進行數據傳送、算術運算、邏輯運算、位操作、控制傳遞等功能的111條基本指令。此外也可以采用C語言進行程序設計。
尋址方式尋址方式是CPU尋找操作數或操作數地址的方法,存放在不同位置的數據具有需要采用不同的方式進行尋址,不同類型計算機的尋址方式也不同,它是計算機重要的性能指標之一。MSC-51單片機有7種尋址方式。
立即尋址指令中直接給出參與操作的數據,稱立即數,用data表示。在匯編語言中,為標明立即數,為data加前綴”#”。立即數可以是8位和16位二進制數,分別用#data和#data16表示。
匯編指令格式:MOV A, #data
如:
MOV A, #30H ;8位立即數30H放入累加器ACC中 MOV DPTR, #2000H ;16位立即數2000H放入數據指針DPTR 直接尋址指令中直接給出參與操作的數據的地址,直接地址一般用direct表示。
匯編指令格式:MOV A, direct
如:
MOV A, 80H ;將80H單元,即P0口的內容放入累加器ACC中 寄存器尋址參與操作的數據存放在寄存器中,匯編指令中直接以寄存器名來表示參與操作的數據地址,寄存器包括工作寄存器R0~R7、累加器ACC、寄存器B、數據指針DPTR。
匯編語言格式:MOV A, Rn ;n=0~7
如:
MOV A, R1 ;將R1中的內容放入累加器ACC中 寄存器間接尋址二次尋址,尋址中寄存器的內容為操作數所存放的地址。第一次尋址得到寄存器的內容為(R0)、(R1)或(DPTR),第二次尋址是將第一次尋址得到的寄存器內容作為地址,在其中存、取參與操作的數據。匯編語言中,寄存器前綴@是寄存器間接尋址的標志,有@R0、@R1、@DPTR等。
匯編語言格式:MOV A, @R0/R1/DPTR
如:
MOV A, @DPTR ;將DPTR所指示的地址單元中的內容放入累加器ACC中 變址尋址由兩個寄存器提供地址。若由ACC、PC提供,在匯編語言指令中尋址地址表示為@A+PC;若由ACC和DPTR提供,在匯編語言指令中尋址地址為@A+DPTR。其中,PC或DPTR被稱為基址寄存器,A被稱為變址寄存器,基址與變址相加為16位無符號加法。
若變址寄存器ACC中的內容加基址寄存器DPTR(或PC)中內容時,低8位有進位,則該進位直接加到高位,不影響進位標志。因變址尋址指令多用于查表,故常稱為查表指令。
匯編語言格式:MOV A, @A+DPTP
如:
MOV A, @A+DPTR ;將A+DPTR所指示的地址單元中的內容放入累加器ACC中 相對尋址以相對尋址指令的下一條指令的程序計數器PC的內容為基值,加上指令機器代碼中的“相對地址”,形成新的PC值(要轉移的指令地址)。指令機器代碼中“相對地址”指的是用一個帶符號的8位二進制補碼表示的偏移字節數,其取值范圍為-128~+127,負數表示向后轉移,正數表示向前轉移。rel代表一個8位帶符號的偏移量,要轉移的指令地址=(PC)+相對尋址指令字節數+rel,“( )”代表存儲單元的內容。
匯編語言格式:SJMP rel
如:
SJMP 08H ;指令代碼為雙字節,該指令將轉到地址為(PC) + 02H + 08H 位尋址參與操作的數據為“位”,而不是字節,是對片內RAM中的位尋址區20H~2FH、SFR中11個可位尋址單元的位進行操作。bit代表內數據存儲器RAM或SFR的直接尋址位。
匯編語言格式:MOV C, bit
如:
MOV C, 00H ;或者寫成 MOV C, 20H.0 ;將字節地址20H的D0位內容放到位累加器C中位尋址的位地址與直接尋址的字節地址形式完全一致,主要由操作碼進行區分。
所有尋址方式的尋址范圍總結如下表:
尋址方式 尋址存儲器范圍立即尋址 程序存儲器ROM
直接尋址 片內RAM低128KB,特殊功能寄存器SFR
寄存器尋址 工作寄存器R0~R7,A,C,DPTR,AB
寄存器間接尋址 片內RAM低128KB,片外RAM
變址尋址 程序存儲器ROM (@A+DPTR,@A+PC)
相對尋址 程序存儲器ROM(相對尋址指令的下一指令PC值加 -128~+127)
位尋址 片內RAM的20H到2FH字節地址的所有位,可位尋址SFR
指令系統 數據傳送指令 指令 功能
MOV (Move) 傳送內部RAM和SFR的數據
MOVX (Move External RAM) 傳送外部RAM的數據(外部RAM只能和累加器ACC之間進行傳送數據)
MOVC (Move Code) 讀取并傳送ROM數據表格中的數據
PUSH (Push onto Stack) 入棧
POP (Pop from Stack) 出棧
XCH (Exchange) 全字節交換
XCHD (Exchange low-order Digit) 低半字節交換
SWAP 高、低字節互換
如:
MOV DPTR, #2000H ;外部RAM單元地址2000H傳入DPTR MOVX A, @DPTR ;外部RAM 2000H單元的數據送入A MOVC A, @A + PC ;ROM A+PC單元的數據送入A PUSH A ;將A中的數據放入堆棧 POP A ;將堆棧頂層的數據放入A XCH A, R0 ;交換A和R0中的數據 XCHD A, R0 ;交換A和R0中的低4字節數據 SWAP A ;交換A的高、低4字節數據 算數運算指令 指令 功能ADD (Addition) 加法
ADDC (Add with Carry) 帶進位加法
SUBB (Subtract with Borrow) 帶借位減法
INC (Increment) 加1
DEC (Decrement) 減1
MUL (Multiply) 乘法
DIV (Divide) 除法
DA (Decimal Adjust) 十進制調整
邏輯運算指令 指令 功能
ANL (AND Logic) 邏輯與
ORL (OR Logic) 邏輯或
XRL (Exclusive-OR Logic) 邏輯異或
CLR (Clear) 清零
CPL (Complement) 取反
RL (Rotate Left) 循環左移
RLC (Rotate Left throught the Carry flag) 帶進位循環左移
RR (Rotate Right) 循環右移
RRC (Rotate Right throught the Carry flag) 帶進位循環右移
控制轉移指令 指令 功能
SJMP (Short Jump) 短轉移,后接偏移量rel
AJMP (Absolute Jump) 絕對轉移,最大轉移范圍為2KB
LJMP (Long Jump) 長轉移,轉移目的地址在0~64KB空間范圍
ACALL (Absolute subroutine Call) 子程序絕對調用,最大調用范圍為2KB
LCALL (Long subroutine Call) 子程序長調用,調用64KB空間范圍內的子程序
RET (Return from subroutine) 子程序返回
RETI (Return from Interruptio) 中斷返回
CJNE (Compare Jump if Not Equal) 比較不相等則轉移
DJNZ (Decrement Jump if Not Zero) 減1后不為0則轉移
JZ (Jump if Zero) 結果為0則轉移
JNZ (Jump if Not Zero) 結果不為0則轉移
JC (Jump if the Carry flag is set) 有進位則轉移
JNC (Jump if Not Carry) 無進位則轉移
JB (Jump if the Bit is set) 位為1則轉移
JNB (Jump if the Bit is Not set) 位為0則轉移
JBC(Jump if the Bit is set and Clear the bit) 位為1則轉移,并清除該位
NOP (No Operation) 空操作
位操作指令 指令 功能
SETB (Set Bit) 將某個位置1
偽指令
偽指令在匯編時不產生機器碼,不影響程序執行,僅指明在匯編時執行一些特殊的操作。
ORG 16位地址:起始指令,用在原程序或數據塊的開始,指明此語句后面目標程序或數據塊存放的起始地址。
如:
ORG 1000H ;后面目標程序或數據塊存放的起始地址為1000H[標號:]DB 字節數據項表:字節定義,將項表中的字節數據存放到從標號開始的連續字節單元中。
如:
SEG: DB 32, 'A', 25H ;SEG~SEG+2地址單元依此存放20H、41H、25H[標號:]DW 雙字節數據項表:字定義,定義16位地址表,16地址按低位地址存低位字。
如:
TAB: DW 1234H, 25H ;TAB~TAB+3地址單元依此存放12H、34H、00H、25H[標號:]DS 數值表達式:保留字節,指示在程序存儲器中保留與標號為起始地址的若干字節單元,單元個數由數值表達式指定。
如:
L1: DS 32 ;L1地址開始保留32個存儲單元名字 EQU 表達式:等值指令,用與給一個表達式賦值或給字符串起名字。之后名字可用做程序地址,數據地址或立即數地址使用。名字必須是一字母開頭的字母數字串。
如:
SPACE EQU 10H ;程序中出現SPACE的地方都用10H代替名字 DATA 直接字節地址:給8位內部RAM單元起個名字,名字必須是一字母開頭的字母數字串,同一單元可起多個名字。
如:
ERROR DATA 80H ;內部RAM 80H單元名為ERROR名字 XDATA 直接字節地址:給8位外部RAM起個名字,名字規定同DATA偽指令。
如:
IO_PORT XDATA 0CF04H ;外部RAM 0CF04H單元名為IO_PORT名字 BIT 位指令:給一可位尋址的位單元起名,規定同DATA偽指令。
如:
SWT BIT 30H ; 30H單元名為SWT[標號:] END:結束指令,指出源程序到此結束。
C語言編程51單片機采用C語言編程后,通過C51編譯器進行編譯后產生目標代碼,下載到單片機內部即可運行。編程時,不同存儲器的尋址和數據類型等細節問題都由編譯器解決,無需像使用匯編語言那樣都必須考慮到,而且其中還有豐富的子程序庫可以直接調用,大大減小編程工作量。此外,編程過程中還可以將C語言和匯編語言交叉使用,提高開發效率。
數據類型C51中定義的數據類型比C語言多幾種擴展數據類型:
bit用于定義為變量的名字,編譯器會對其分配地址,位變量分配在內部RAM的20H~2FH單元相應的位區域,位地址范圍是00~7FH,共128個。
sbit用于定義位變量的名字和地址,地址是確定的且不用編譯器分配。它是SFR中的可以進行位尋址的確定位,也可是內部RAM的20H~2FH單元中確定的位。
sfr用于訪問一個內存單元,利用它可以訪問51單片機內部的所有SFR,一般用來聲明SFR。
存儲器類型C51是面向8051單片機的程序語言,應用程序中使用的任何變量或常量必須以一定的存儲器類型定位于單片機的相應的存儲區域中,因此在定義變量類型時,還需要定義它的存儲器類型:
對于單片機來說,訪問片內RAM比訪問片外RAM的速度要快得多,所以對于經常使用的變量應該置于片內RAM中,要用bdata、data、idata來定義;對于不經常使用的變量或規模較大的變量應該置于片外RAM中,要用pdata、xdata來定義。
中斷函數使用C51編寫中斷程序時,需要遵循如下格式:
“`C
void 函數名(void) interrupt 中斷號 [using 工作寄存器組號] {
……
}
“`
更新歷史:
* 2017.11.23 完成初稿
原文鏈接
評論