1. 程式人生 > >C51彙編偽指令(轉載)

C51彙編偽指令(轉載)

1、DS ---預留儲存區命令
格式: 〔標號:〕 DS   表示式值
其功能是從指定地址開始,定義一個儲存區,以備源程式使用。
儲存區預留的儲存單元數由表示式的值決定。
TMP:   DS   1
從標號TEP地址處開始保留1個儲存單元(位元組)。
2、BIT---定義位命令
格式:   字元名稱   BIT   位地址
其功能用於給字元名稱定義位地址。
SPK   BIT   P3.7
經定義後,允許在指令中用SPK代替P3.7。
3、USING指令
USING指令通知彙編器使用8051的哪一個工作暫存器組。
格式: USING 表示式 (值必須為0-3,預設值為0。)
USING 0
使用第0組工作暫存器。
4、SEGMENT指令
SEGMENT 指令用來宣告一個再定位段和一個可選的再定位型別。
格式: 再定位段名 SEGMENT 段型別〔再定位型別〕
其中,“再定位段名”用於指明所宣告的段。
“段型別”用於指定所宣告的段將處的儲存器地址空間。
可用的段型別有 CODE、XDATA、DATA、IDATA和BIT。
STACK_SEG SEGMENT IDATA
DATA_SEG SEGMENT DATA
5、RSEG---再定位段選擇指令
再定位段選擇指令為RSEG,用於選擇一個已在前面定義過的再定位段作為當前段。
格式: RSEG 段名
段名必須是在前面已經宣告過的再定位段。
DATA_SEG SEGMENT DATA   ;宣告一個再定位DATA段
RSEG   DATA_SEG   ;選擇前面宣告的再定位DATA段作為當前段
6、絕對段選擇指令
CSEG---絕對程式碼段
DSEG---內部絕對資料段
XSEG---外部絕對資料段
ISEG---內部間接定址資料段
BSEG---絕對位定址資料段
格式:
CSEG [AT 絕對地址表示式]
DSEG [AT 絕對地址表示式]
XSEG [AT 絕對地址表示式]
ISEG [AT 絕對地址表示式]
BSEG [AT 絕對地址表示式]
括號內是可選項,用來指定當前絕對段的基地址。
CSEG AT 0000H
AJMP MAIN
7、ORG指令
ORG指令用來改變彙編器的計數器,從而設定一個新的程式起始地址。
格式: ORG 表示式
表示式必須是絕對或簡單再定位表示式。
ORG 0000H
AJMP MAIN
設定 MAIN 程式的起始地址為 0000H。
8、END指令
END指令用來控制彙編結束。在每個彙編程式的最後一行必須有一條END指令,
並且END指令只能出現一次。
9、EQU指令
EQU 指令用於將一個數值或暫存器名賦給一個指定的符號名。
格式: 符號名   EQU   表示式
或     符號名   EQU   暫存器名
表示式必須是一個簡單再定位表示式。
用 EQU 指令賦值以後的字元名,可以用作資料地址、程式碼地址、位地址或者
直接當做一個立即數使用。
LIMIT   EQU   1200
COUNT   EQU   R5
10、DATA 指令
DATA 指令用於將一個內部 RAM 的地址賦給指定的符號名。
格式: 符號名   DATA   表示式
數值表示式的值在 0-255 之間,表示式必須是一個簡單再定位表示式。
PORT1   DATA   40H
11、DB 指令
DB 指令以表示式的值的位元組形式初始化程式碼空間。
格式: [標號:]   DB   表示式表
表示式中可包含符號、字串、或表示式等項,各個項之間用逗號隔開,字串應用引號括起來。
括號內的標號是可選項,如果使用了標號,則標號的值將是表示式表中第一位元組的地址。
DB 指令必須位於 CODE 段之內,否則將會發生錯誤。
TABLE:
DB 0C0H, 0F9H, 0A4H
TABLE1:
DB " 89C51 "
51彙編程式基本框架
向大家介紹一種可以不用 EQU來定義變數的方法。
先說說用 EQU 定義變數的缺點:
1:人為為每一個變數指定地址,還必須注意防止地址衝突,工作量太大。
2:編譯器只是把用 EQU 定義的識別符號當作常數而已,在很多情況下當用戶把該識別符號用錯時,編譯器不會給出警告或報錯。
  例如,假設想在 IDATA 區定義一個變數,如果用 EQU 方式作如下定義:
  MYBYTE EQU 87H   ;(其實編譯器只是將 MYBYTE 視為一個常量而已)如果想將該變數(位於 IDATA 區)賦值到累加器 A,正確的訪問方式應該是
 MOV R0,#MYBYTE
  MOV A,@R0
  如果程式設計師將上面的語句錯寫為:
  MOV A,MYBYTE
  (原因可能是粗心,或者忘記了 MYBYTE 是大於 7FH 的)
  編譯器不會為此報錯,結果執行的操作是將地址為 87H 的特殊功能暫存器的內容賦值到 A,而不是將 IDATA 區的 87H 賦值到 A,與使用者的本意大相徑庭。
這只是一個例子,實際上還會有其它類似的問題。
如果使用了下面描述的方式,則編譯器會幫你指出此類錯誤。建議 EQU 只用於定義常數,不要做其它用途。
下面是一種比較好的變數定義方法,沒有上面所說的缺點。
;定義變數的方法:
;1:定義位元組變數用 DS 關鍵字,語法為:
;   變數名: DS 分配的位元組數
;2:定義位變數用 DBIT 關鍵字,語法為:
;   位變數名:   DBIT 分配的位數
;3:定義特殊功能暫存器(SFR)用 DATA 關鍵字,語法為:
;   暫存器名: DATA 暫存器地址
;4:定義可位定址的特殊功能暫存器中的位用 BIT 關鍵字,語法為:
;   位名: BIT 位地址
;5:常量定義用 EQU 關鍵字,語法為:
;   常量名: EQU 常數
;具體見如下示例:
;51彙編程式基本框架
$NOMOD51   ;如果不使用預設的 51 特殊功能暫存器定義,可以用本語句取消。
;$INCLUDE   (W79E825.INC)   ;用此語句可以包含標頭檔案
;---------- 特殊功能暫存器定義 (僅作示範,不全)
  P0     DATA   080H
  SP     DATA   081H
  DPL   DATA   082H
  DPH   DATA   083H
 PCON   DATA   087H
  TCON   DATA   088H
  TMOD   DATA   089H
  TL0   DATA   08AH
  TL1   DATA   08BH
  TH0   DATA   08CH
  TH1   DATA   08DH
  P1     DATA   090H
  SCON   DATA   098H
  SBUF   DATA   099H
  P2     DATA   0A0H
  IE     DATA   0A8H
  PSW   DATA   0D0H
;---------- 可位定址的特殊功能暫存器中的位定義(僅作示範,不全)
  BITIT0     BIT TCON.0 ;外部中斷0觸發方式
  BITIE0     BIT TCON.1 ;外部中斷0標誌
  BITIT1     BIT TCON.2 ;外部中斷1觸發方式
  BITIE1     BIT TCON.3 ;外部中斷1標誌
  BITTR0     BIT TCON.4 ;定時器0啟動控制
  BITTF0     BIT TCON.5 ;定時器0溢位標誌
  BITTR1     BIT TCON.6 ;定時器1啟動控制
  BITTF1     BIT TCON.7 ;定時器1溢位標誌
  BITRI     BIT SCON.0 ;接收中斷標誌
  BITTI     BIT SCON.1 ;傳送中斷標誌
  BITRB8     BIT SCON.2
  BITTB8     BIT SCON.3
  BITREN     BIT SCON.4 ;接收使能
  BITSM2     BIT SCON.5 ;多機通訊控制
  BITSM1     BIT SCON.6 ;串列埠模式位1
  BITSM0_FE   BIT SCON.7 ;串列埠模式位0或FE
;---------- 常量定義
NSTACKSIZE     EQU 36   ;指定堆疊大小
;---------- 以下為變數定義
;如果MCU沒有某些資料段,就刪除或註釋掉相應的段。
;變數定義有不可重定位和可重定位之分,這二種方式可混合使用。
;需要注意的是,某些編譯器對可重定位方式支援的不是很好,
;而且可重定位方式對彙編不是很有用,所以建議不用可重定位方式。
;---- 下面為不可重定位的變數分配方式
; BSEG 關鍵詞指定 BIT 區
; DSEG 關鍵詞指定 DATA 區
; ISEG 關鍵詞指定 IDATA 區
; XSEG 關鍵詞指定 XDATA 區
; CSEG 關鍵詞指定 CDATA 區
;注意:BIT 區的位地址 20H~2FH 範圍與 DATA 區的00H~7FH範圍是同一儲存空間,
; 所以在分配 DATA 區位元組變數和 BIT 區位變數時要注意不要重疊。
  BSEG   AT 00H ;從 BIT 區的位地址 00H 開始分配位變數
BEXAMPLE:     DBIT 1 ;在 BIT 區定義一個位變數,位地址為 00H(即DATA區20H位元組的第0位)
BTESTA:       DBIT 1 ;在 BIT 區定義一個位變數,位地址為 01H(即DATA區20H位元組的第1位)
BTESTB:       DBIT 1 ;在 BIT 區定義一個位變數,位地址為 02H(即DATA區20H位元組的第2位)
;在 DATA 區定義變數時要注意不要與 R0~R7 暫存器重疊。
  DSEG   AT 08H ;從 DATA 區的 08H 地址(為了避開 R0~R7)開始分配變數
DEXAMPLE:     DS   2 ;在 DATA 區定義一個 2 位元組的變數,地址為 08H
DTEST:       DS   1 ;在 DATA 區定義一個 1 位元組的變數,地址為 0AH
DLCDBUFFER:   DS   21 ;注意不要與 BIT 區重疊,建議在地址 1FH 結束分配。
DSEG   AT   2EH ;在 DATA 區的可位定址區域定義可位定址的位元組變數
              ;注意不要與前面在 BIT 區分配的 BIT 位重疊
DBYTEA:       DS   1 ;在 DATA 區定義一個 1 位元組的變數,地址為 2EH(此變數可位定址)
DBYTEB:       DS   1 ;在 DATA 區定義一個 1 位元組的變數,地址為 2FH(此變數可位定址)
DSEG   AT 30H ;從 DATA 區的 30H 地址(已避開 BIT 區)開始分配變數
DBYTEC:       DS   1 ;在 DATA 區定義一個 1 位元組的變數,地址為 30H
DBYTED:       DS   3 ;在 DATA 區定義一個 3 位元組的變數,地址為 31H
DBYTEE:       DS   1 ;在 DATA 區定義一個 1 位元組的變數,地址為 34H
ISEG   AT 80H ;從 IDATA 區的 80H 地址(為了避開 DATA 區)開始分配變數
IEXAMPLEA:     DS   1 ;在 IDATA 區定義一個 1 位元組的變數,地址為 80H
IEXAMPLEB:     DS   4 ;在 IDATA 區定義一個 4 位元組的變數,地址為 81H
ISEG   AT 255-NSTACKSIZE   ;將堆疊放在 IDATA 區的末尾,首地址為 255-NSTACKSIZE
ISTACK:       DS   NSTACKSIZE ;定義多位元組變數,作為堆疊用(大小為 NSTACKSIZE),
                    ; 見後面程式碼中的 “MOV   SP,#ISTACK”語句。
XSEG   AT 00H   ;從 XDATA 區的 00H 地址開始分配變數
XEXAMPLE0:     DS   1 ;在 XDATA 區定義一個 1 位元組的變數,地址為 00H
XEXAMPLE1:     DS   1 ;在 XDATA 區定義一個 1 位元組的變數,地址為 01H
;==============================================================================;
;CODE 段
  CSEG   AT 0   //程式起始地址
A_START:
  MOV   IE,#00H ;關閉中斷
  SJMP   A_MAIN
  CSEG   AT 0023H   //串列埠中斷地址,其它中斷地址的指定類似此方法。
  LJMP   A_UARTINT   //跳轉到中斷處理子函式
;==============================================================================;
A_MAIN:
  MOV   SP,#ISTACK ;設定堆疊指標,
              ;只能在呼叫任何函
              ; 數之前設定SP。
  MOV   PSW,#0 ;將RS0,RS1及其它標誌位清0。
;注意:記憶體清零不要放在子函式中,
;     因為記憶體清零也會清零堆疊,
;     從而導致 RET 返回地址不正確!!!
  MOV   R0,#0FFH   ;記憶體00H~0FFH的內容清零。
  CLR     A
A_MAIN01:
  MOV   @R0,A
  DJNZ   R0,A_MAIN01
;使用者初始化程式碼
...
A_LOOP: ;主迴圈
;使用者程式碼
  LCALL _TEST
  SJMP   A_LOOP
;使用者程式碼(子程式)
_TEST:
  NOP
  NOP
  RET
A_UARTINT: //串列埠中斷處理子函式
  NOP
  NOP
  RETI
 END

------------------------------------------------------------------------------------

A51

彙編器是運行於IBM PC系列及其相容機上的交叉彙編軟體,其主要功能是將MCS-51系列微控制器組合語言源程式翻譯成符合Intel目標檔案格式的可再定位的目的碼,經過L51聯結器的連線和裝配,產生可被DS51模擬器除錯或其它任何一種與Intel 目標檔案格式相容的模擬器使用的絕對目的碼.

:A51的符號:

A51中可使用符號表示數值(EQU),地址和暫存器名,符號具有段型別,作用域,值域和可變性等屬性.

符號的段屬性:

指出符號所位於的地址空間.段型別有:

NUMBER

無型別符號

DATADATA

段符號(可直接定址的內部RAM空間)

IDATAIDATA

段符號(可間接定址的內部RAM空間)

XDATAXDATA

段符號(外部資料儲存空間)

BITBIT

段符號(內部RAM低地址區的可位定址的空間)

CODECODE

段符號(程式儲存器空間)

REGISTER

暫存器符號

作用域:指出符號是外部的,區域性的還是全域性的.(PUBLIC,EXTRN

關鍵字說明)

:標號:定義標號時,標號名後必須接冒號

:

,以示區別,每行只能定義一個標號,標號一經定義,其值為當前地址計數器的當前值,因此標號代表了指令和資料的地址,不能重複定義.

:特殊的彙編符號:A51

巨集組合語言定義了代表CPU暫存器的特殊符號,這些是保留的關鍵字,AR0---AR7:表示當前工作暫存器的R0R7的絕對地址,它的值取決於指令所選擇的工作暫存器組.

:運算子:

有三種1):算術運算子包括:+,-(正負號),---+,,,,MOD(取模),()—括號,改變運算順序.2):二進位制運算子號:用來對二進位制數進行按位取反,移位或邏輯運算.包括:NOT(按位取反),HIGH(取右邊運算元的高8,LOW(取右邊運算元的低8)SHR(右移位),SHL(左移位),AND(邏輯與),OR(邏輯或),XOR(邏輯異或).3):關係運算符:>=,<=,<>,=,<,>.

所有運算子的優先順序順序:()àNOT,HIGH,LOWà+,-(正負號)à*,/,MODà+,-(加減)àSHR,SHLàAND,OR,XORà

>=,<=,<>,>,<,=.

數值表示式:

數值表示式由運算子和運算元組成,一個運算元又可以是表示式,與符號具有段屬性一樣,表示式也具有段型別屬性,表示式的型別依賴於運算元的型別.表示式的型別如下:BIT,NUMBER,CODE,DATA,IDATA,XDATA.大多數的表示式是無型別的,當表示式中包含有段型別的運算元或者是子表示式時,運算結果的段型別遵循下面的原則:

對於單目運算子:(+/-/HIGH/LOW/NOT)表示式的結果與運算元具有相同的型別

.

對於所有的雙目運算子(+/-),表示式的結果均為無型別的結果

.

對加減運算,只有當其中的一個運算元具有段型別的時候,運算結果才具有相同的段型別,如果兩個運算元具有段型別,即使他們的段型別一樣,結果也是無型別的

(NUMBER).

總結:只有當運算元加上或者是減去一個無型別時,才可能產生一型別,其他所有的組合均產生無型別的表示式

.

A51提供了偽指令,

可以利用這些偽指令在彙編程式中定義符號,保留和初始化儲存空間,定位目的碼等功能,偽指令中除DB,DW外均不產生目的碼,但可以改變彙編器的狀態,並將有關資訊(如段定義)加到目標檔案中.

偽指令分四類

:

1):定義符號:SEGMENT,EQU,SET,DATA,IDATA,XDATA,BIT,CODE

2):

保留和初始化儲存空間:DS,DB,DW,DBIT

3):程式連結:

PUBLIC,EXTRN,NAME

4):

彙編狀態控制和段選擇

:ORG,

END,RSEG,CSEG,DSEG,XSEG,ISEG,BSEG,USING

一 :定義符號的偽指令

1

SEGMENT

格式:段名符號SEGMENT段型別[再定位型別]

SEGMENT

指令可宣告一個可再定位(區別於CSEG,DSEG,XSEG,BSEG,ISEG等 定義的在相對應的空間固定地址定義的絕對段—在連線的過程中不允許重新定位)的段符號和一個可選的再定位型別,段符號可以用來定義段,L51聯結器可將多個模組內的具有相同段名和再定位型別的幾個段合成為一個段.段型別說明了段所處的地址空間.

如果是編寫的彙編程式要與C源程式介面,即被C源程式呼叫,則全部的彙編子程式所命名的定義的程式碼段的段名必須是可用SEGMENT來定義的,而且名字的命名的方法也應該參照C51編譯器產生的區域性段的段名的轉換規則.段名的作用主要是在彙編的時候用RSEG來啟用的,在連線定位的時候用到的.與段名相應的是用於儲存和傳遞引數的別名,可以在彙編源程式中直接應用區域性段的別名,這個別名主要是在傳遞函式引數的時候用的.在彙編程式中要用PUBLIC 宣告被其他模組引用的全域性符號.

DATA(

可直接定址的內部RAM空間)

IDATA(

可間接定址的內部RAM空間)

XDATA(

外部資料儲存空間)

BIT(

內部RAM低地址區的可位定址的空間)

CODE(

程式儲存器空間)

可選的再定位型別定義了L51連線時的定位方式,再定位型別

:

UNIT:

定義一個可開始於任一單元的段對於BIT型的段,一個單元是一個位,

其它所有的段一個單元是一個位元組

.

PAGE:

定義一個起始地址必須是256的整數倍的段,段的絕對地址由L51自己計算,該型別只允許用於XDATACODE型別段.

INPAGE:

定義一個由L51連線後必須包含在256B的塊中,只適用於XDATACODE.

INBLOCK:

定義一個L51連線後必須包含在2KB中的段,只適用於CODE.

OVERLAYABLE:定義一個可與其他段交疊的覆蓋段,其段名符號必須按C51或者PL/M51的規則命名.C51把區域性資料段和區域性位段定義成?DT?FUNCTIONNAME?MODULENAME?BI?FUNCTIONNAME?MODULENAME這是在small模式下.其他的模式略有不同。

BITADDRESSABLE:

定義一個L51連線後位於可位定址的區,段長不能超過16B.

2)EQU

格式: 符號名 EQU 表示式

符號名 EQU暫存器名

EQU

偽指令定義一表示數值或暫存器的符號,該符號可用於表示式或助記符指令的運算元,EQU指令定義的符號不能被改變或重新定義,其段型別取決於表示式中的運算元型別型別,無型別的EQU符號可用於任何表示式中.

LIMITEQU200

VALUEEQULIMIT-100+A

COUNTER EQUR5

3)SET

格式: 符號名 SET 表示式

符號名 SET 暫存器名

SET

指令的功能與EQU指令的功能一樣,區別是SET指令定義的符號可以再定義和改變.

VALUEEQU200

VALUESETVALUE/2

COUNTERSETR1

TEMPSETCOUNTER/2

4)BIT

格式:符號名 BIT 表示式

BIT

指令定義一表示位地址的符號,該符號一經定義便不能重新定義和改變.

DATA_BSEG SEGMENTBIT

RSEGDATA_BSEG

CTRLDS1

FLAGBITCTRL.1

FLAG2BITFLAG+1

5)DATA

格式:符號名 DATA表示式

DATA

指令定義一表示MCS-51內部資料儲存器位元組地址的符號,表示式必須是一個絕對地址值或者是一個簡單的再定位表示式(即數值確定的,且其值必須在0255之間,型別必須是DATA或者是NUMBER型別)

例如在彙編程式中:

PORTDATA90H

RESULT_LDATA40H

RESULT_HDATARESULT_L+1

6) XDATA,IDATA,CODE

均是也和DATA一樣,都是定義一個代表相應儲存空間單元的地址符號,表示式也必須是相對應的型別或者是NUMBER型別。

二 初始化和保留指令

1)

DS

格式:[標號:] DS 表示式

DS

指令以位元組為單位,在內部或者外部地址空間中保留儲存空間,表示式中不能包含前向地址參考量,可為除BIT段的任何型別。該偽指令語句使當前地址計數器加上表達式的值,需要注意的是地址計數器加上表達式結果的值不能超出地址空間的範圍。(無論是彙編器還是編譯器,對每一種不同型別的地址空間(DATA,CODE,PDATA,XDATA,BIT)都產生一個獨立的地址計數器,每彙編一條指令,計數器都會自動增加,不過可以用ORG偽指令改變當前段地址計數器,用ORG偽指令表示式的值作為當前段地址計數器的初值,而當前段的改變可以用RSEG偽指令來改變。

RSEG ?DT?FUNCTION?MODULENAE----

聲明當前段為區域性資料段

?FUNCTION?BYTE:-------------

函式區域性段的別名

TIME:DS5

2) DBIT

格式[標號:]DBIT

表示式

以位為單位在可位定址段內保留儲存空間, 表示式中不能包含前向地址參考量或者是再定位的符號和外部符號,該指令使當前地址計數器增加表示式結果值,其增加量以位為單位

.

3) DB DW

格式:[標號]:DB/DW表示式1[,表示式2,………]

這兩個指令的作用相同,均是以位元組或者是字初始化程式儲存空間,上面是保留儲存空間,儲存空間可以使RAMROM,而這兩個指令直接就是初始化程式儲存空間

.

Table: DB“any key to continue!”

Requst: DBLOW(Table),HIGH(Table)