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
本文引用地址: http://www.21ic.com/app/mcu/201901/786307.htm
------------------------------------------------------------------------------------
A51
匯編器是運行于IBM PC系列及其兼容機上的交叉匯編軟件,其主要功能是將MCS-51系列單片機匯編語言源程序翻譯成符合Intel目標文件格式的可再定位的目標代碼,經過L51連接器的連接和裝配,產生可被DS51仿真器調試或其它任何一種與Intel 目標文件格式兼容的仿真器使用的絕對目標代碼。
一:A51的符號:
在A51中可使用符號表示數值(EQU),地址和寄存器名,符號具有段類型,作用域,值域和可變性等屬性。
符號的段屬性:
指出符號所位于的地址空間。段類型有:
NUMBER
無類型符號
DATA DATA
段符號(可直接尋址的內部RAM空間)
IDATA IDATA
段符號(可間接尋址的內部RAM空間)
XDATA XDATA
段符號(外部數據存儲空間)
BIT BIT
段符號(內部RAM低地址區的可位尋址的空間)
CODE CODE
段符號(程序存儲器空間)
REGISTER
寄存器符號
作用域:指出符號是外部的,局部的還是全局的。(PUBLIC,EXTRN
關鍵字說明)
二:標號:定義標號時,標號名后必須接冒號”:
”,以示區別,每行只能定義一個標號,標號一經定義,其值為當前地址計數器的當前值,因此標號代表了指令和數據的地址,不能重復定義。
三:特殊的匯編符號:A51
宏匯編語言定義了代表CPU寄存器的特殊符號,這些是保留的關鍵字,AR0---AR7:表示當前工作寄存器的R0—R7的絕對地址,它的值取決于指令所選擇的工作寄存器組。
四:運算符:
有三種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自己計算,該類型只允許用于XDATA和CODE類型段。
INPAGE:
定義一個由L51連接后必須包含在256B的塊中,只適用于XDATA和CODE段。
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符號可用于任何表達式中。
LIMIT EQU 200
VALUE EQU LIMIT-100+’A’
COUNTER EQU R5
3) SET
格式: 符號名 SET 表達式
符號名 SET 寄存器名
SET
指令的功能與EQU指令的功能一樣,區別是SET指令定義的符號可以再定義和改變。
VALUE EQU 200
VALUE SET VALUE/2
COUNTER SET R1
TEMP SET COUNTER/2
4) BIT
格式: 符號名 BIT 表達式
BIT
指令定義一表示位地址的符號,該符號一經定義便不能重新定義和改變。
DATA_BSEG SEGMENT BIT
RSEG DATA_BSEG
CTRL DS 1
FLAG BIT CTRL.1
FLAG2 BIT FLAG+1
5) DATA
格式: 符號名 DATA 表達式
DATA
指令定義一表示MCS-51內部數據存儲器字節地址的符號,表達式必須是一個絕對地址值或者是一個簡單的再定位表達式(即數值確定的,且其值必須在0—255之間,類型必須是DATA或者是NUMBER類型)
例如在匯編程序中:
PORT DATA 90H
RESULT_L DATA 40H
RESULT_H DATA RESULT_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: DS 5
2) DBIT
格式 [標號:] DBIT
表達式
以位為單位在可位尋址段內保留存儲空間, 表達式中不能包含前向地址參考量或者是再定位的符號和外部符號,該指令使當前地址計數器增加表達式結果值,其增加量以位為單位
。
3) DB DW
格式: [標號]: DB/DW 表達式1[,表達式2,………]
這兩個指令的作用相同,均是以字節或者是字初始化程序存儲空間,上面是保留存儲空間,存儲空間可以使RAM和ROM,而這兩個指令直接就是初始化程序存儲空間
。
Table: DB “any key to continue!”
Requst: DB LOW(Table),HIGH(Table)
評論
查看更多