Keil C51開發系統基本知識
1. 第一節 系統概述
Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發系統,與匯編相比,C語言在功能上、結構性、可讀性、可維護性上有明顯的優勢,因而易學易用。用過匯編語言后再使用C來開發,體會更加深刻。
Keil C51軟件提供豐富的庫函數和功能強大的集成開發調試工具,全Windows界面。另外重要的一點,只要看一下編譯后生成的匯編代碼,就能體會到Keil C51生成的目標代碼效率非常之高,多數語句生成的匯編代碼很緊湊,容易理解。在開發大型軟件時更能體現高級語言的優勢。
下面詳細介紹Keil C51開發系統各部分功能和使用。
2. 第二節 Keil C51單片機軟件開發系統的整體結構
C51工具包的整體結構,如圖(1)所示,其中uVision與Ishell分別是C51 for Windows和for Dos的集成開發環境(IDE),可以完成編輯、編譯、連接、調試、仿真等整個開發流程。開發人員可用IDE本身或其它編輯器編輯C或匯編源文件。然后分別由C51及A51編譯器編譯生成目標文件(.OBJ)。目標文件可由LIB51創建生成庫文件,也可以與庫文件一起經L51連接定位生成絕對目標文件(.ABS)。ABS文件由OH51轉換成標準的Hex文件,以供調試器dScope51或tScope51使用進行源代碼級調試,也可由仿真器使用直接對目標板進行調試,也可以直接寫入程序存貯器如EPROM中。
圖(1) C51工具包整體結構圖
3. 第三節 Keil C51工具包的安裝
1. 1. C51 for Dos
在Windows下直接運行軟件包中DOS\C51DOS.exe然后選擇安裝目錄即可。完畢后欲使系統正常工作須進行以下操作(設C:\C51為安裝目錄):
修改Autoexec.bat,加入
path=C:\C51\Bin
Set C51LIB=C:\C51\LIB
Set C51INC=C:\C51\INC
然后運行Autoexec.bat
2. 2. C51 for Windows的安裝及注意事項:
在Windows下運行軟件包中WIN\Setup.exe,最好選擇安裝目錄與C51 for Dos相同,這樣設置最簡單(設安裝于C:\C51目錄下)。然后將軟件包中crack目錄中的文件拷入C:\C51\Bin目錄下。
4. 第四節 Keil C51工具包各部分功能及使用簡介
1. 1. C51與A51
1. (1) C51
C51是C語言編譯器,其使用方法為:
C51 sourcefile[編譯控制指令]
或者
C51 @ commandfile
其中sourcefile為C源文件(.C)。大量的編譯控制指令完成C51編譯器的全部功能。包控C51輸出文件C.LST,.OBJ,.I和.SRC文件的控制。源文件(.C)的控制等,詳見第五部分的具體介紹。
而Commandfile為一個連接控制文件其內容包括:.C源文件及各編譯控制指令,它沒有固定的名字,開發人員可根據自己的習慣指定,它適于用控制指令較多的場合。
2. (2) A51
A51是匯編語言編譯器,使用方法為:
A51 sourcefile[編譯控制指令]
或A51 @ commandfile
其中sourcefile為匯編源文件(.asm或.a51),而編譯控制指令的使用與其它匯編如ASM語言類似,可參考其他匯編語言材料。
Commandfile同C51中的Commandfile類似,它使A51使用和修改方便。
2. 2. L51和BL51
1. (1) L51
L51是Keil C51軟件包提供的連接/定位器,其功能是將編譯生成的OBJ文件與庫文件連接定位生成絕對目標文件(.ABS),其使用方法為:
L51 目標文件列表[庫文件列表] [to outputfile] [連接控制指令]
或 L51 @Commandfile
源程序的多個模塊分別經C51與A51編譯后生成多個OBJ文件,連接時,這些文件全列于目標文件列表中,作為輸入文件,如果還需與庫文件(.LiB)相連接,則庫文件也必須列在其后。outputfile為輸文件名,缺少時為第一模塊名,后綴為.ABS。連接控制指令提供了連接定位時的所有控制功能。Commandfile為連接控制文件,其具體內容是包括了目標文件列表,庫文件列表及輸出文件、連接控制命令,以取代第一種繁瑣的格式,由于目標模塊庫文件大多不止1個,因而第2種方法較多見,這個文件名字也可由使用者隨意指定。
2. (2) Bl51
BL51也是C51軟件包的連接/定位器,其具有L51的所有功能,此外它還具有以下3點特別之處:
a. 可以連接定位大于64kBytes的程序。
b. 具有代碼域及域切換功能(CodeBanking & Bank Switching)
c. 可用于RTX51操作系統
RTX51是一個實時多任務操作系統,它改變了傳統的編程模式,甚至不必用main( )函數,單片機系統軟件向RTOS發展是一種趨勢,這種趨勢對于186和386及68K系列CPU更為明顯和必須,對8051因CPU較為簡單,程序結構等都不太復雜,RTX51作用顯得不太突出,其專業版軟件PK51軟件包甚至不包括RTX51Full,而只有一個RTX51TINY版本的RTOS。RTX51 TINY適用于無外部RAM的單片機系統,因而可用面很窄,在本文中不作介紹。Bank switching技術因使用很少也不作介紹。
3. 3. DScope51,Tscope51及Monitor51
1. (1) dScope51
dScope51是一個源級調試器和模擬器,它可以調試由C51編譯器、A51匯編器、PL/M-51編譯器及ASM-51匯編器產生的程序。它不需目標板(for windows也可通過mon51接目標板),只能進行軟件模擬,但其功能強大,可模擬CPU及其外圍器件,如內部串口,外部I/O及定時器等,能對嵌入式軟件功能進行有效測試。
其使用方法為:
DS51[debugfile][INIT(initfile)]
其中debugfile是一個Hex格式的8051文件,即待調試的文件其為可選的,可在進入dScope51后用load命令裝入。
Initfile為一個初使化文件,它在啟動dScope51后,在debugfile裝入前裝入,裝有一些dScope的初使化參數及常用調試函數等。下面是一個dScope.ini文件(for dos)的內容:
Load ..\..\ds51\8051.iof
Map 0,0xffff
dScope51 for Windows則直接用鼠標進入,然后用load裝入待調文件。
2. (2) tScope51
與dScope51不同的是Scope51必須帶目標板,目前它可以通過兩種方式訪問目標板。(1) 通過EMul51在線仿真器,tScope51為該仿真器準備了一個動態連接文件EMUL51.IOT,但該方法必須配合該仿真器。(2) 通過Monitov51監控程序,這種方法是可行的,tScope51為訪問Monitor51專門帶有MON51.IOT連接程序,使用時可通過串口及監控程序來調試目標板。
其使用方法為:
TS51[INIT(file_name.ini)]
其中file_name.ini為一個初使化文件。
進入TS51后,必須裝入IOT文件,可用的有MON51.IOT及EMUL51.IOT兩種,如裝入MON51.IOT:
Load.C:\C51\TS51\MON51.IOT CPUTYPE(80517)
可惜的是tScope51只有for Dos的版本。
3. (3) Monitor 51
Monitor51是一個監控程序通過PC機的串口與目標板進行通信,Monitor操作需要MON51或dScope51 for Windows,后面部分將對Monitor51做較為詳細的介紹。
4. 4. Ishell及uVision
1. (1) Ishell for Dos
這是一個for Dos的IDE,直接在命令行鍵入Ishell,則進入該環境,它使用簡單方便。其命令行與DOS命令行具有同樣的功能,對單模塊的Project直接由菜單進行編譯連接,對多模塊的project。則通過批處理,BAT文件進行編譯連接,然后通過菜單控制由dScope51或tScope51對程序進行調試,因為是for dos的,不做太詳細介紹。
2. (2) uVision for Windows
uVision for Windows是一個標準的Windows應用程序,它是C51的一個集成軟件開發平臺,具有源代碼編輯、project管理、集成的make等功能,它的人機界面友好,操作方便,是開發者的首選,具體配置及使用見第五部分。
2. 第二章 Keil C51軟件使用詳解
1. 第一節 Keil C51編譯器的控制指令
C51編譯器的控制指令分為三類:源文件控制類,目標文件控制類及列表控制類。
1. 1. 源文件控制類
NOEXTEND:C51源文件不允許使用ANSI C擴展功能。
DEFINE(DF):定義預處理(在C51命令行)。
2. 2. 目標文件(Object)控制類:
COMPACT LARGE SMALL 選編譯模式
DEBUG(DB) 包含調試信息,以供仿真器或dSCope51使用。
NOAMAKE(NOAM) 禁止AutoMake信息記錄
NOREGPARMS 禁止用寄存器傳遞參數
OBJECTEXTEND(OE) Object文件包含附加變量類型信息
OPTIMIZE(OT) 指定優化級別
REGFILE(RF) 指定一個寄存器使用的文件以供整體優化用
REGISTERBANK(RB) 指定一個供絕對寄存器訪問的寄存器區名
SRC 不生成目標文件只生成匯編源文件
其它控件不常用。
3. 3. 列表文件(listing)控制類:
CODE(CD):向列表文件加入匯編列表
LISTINCLUDE(LC):顯示indude文件
SYMBOLS(SB):列表文件包括模塊內所有符號的列表
WARNINGLEVEL(WL):選擇“警告”級別
2. 第二節 dScope51的使用
1. 1. dScope51 for Dos
總的來說dScope51具有以下特性:
l 高級語言顯示模式
l 集成硬件環境模擬
l 單步或“GO”執行模式
l 存儲器、寄存器及變量訪問
l Watch表達式之值
l 函數與信號功能
下面,具體說明在進入dScope51 for Dos之后,如何實現上述功能,dScope51采用下拉菜單格式和窗口顯示控制,共有language、serial、exe、register四個窗口,其中exe為命令行窗口,language為程序窗口,serial為串口窗,register為寄存器窗。
1. (1) 高級語言顯示模式
單擊主菜單中的“View”,第一欄中的三條命令“Highlevel”、“Mixed”、“Assembly”分別對所裝入的程序按照“高級”、“混合級”及“匯編級”三種方式顯示,以方便調試使用。
2. (2) 集成硬件環境模擬顯示
主菜單中“Peripheral”各條能顯示模擬硬件環境的狀態,其中:
i/o Port:顯示各I/O口之值,對8031而言SFR中的P1、P2、P3、P0與引腳之值分別列出:
Interrupt:顯示5個中斷源的入口模式是否允許,優先級等中斷狀態。
Timer:顯示各定時/計數器的模式,初始值狀態等。
int Message:中斷信息允許,如為允許(“>>”出現),則當中斷申請時,顯示中斷源信息。比如當中斷發生時會顯示:
“interrupt Timer 0 occured”等
A/D converter:
顯示A/D轉換器狀態無時,則提示“無”。
Serial:串口信息顯示,包括串口模式、波特產等
Other:其它器件,如為8031則顯示“ 無”
3. (3) 單步或“Go”執行
“F8”單步執行,“F5”全速執行到斷點。或選主菜單中Trace單步執行CPU中的Go全速執行。
4. (4) 存儲器寄存器及變量訪問
外部存儲器管理MAP菜單:設置(set)、取消(reset)、顯示(Display)處理可用存儲空間。
修改Code代碼:ASM命令
存儲器顯示命令:D 類別為(X、D、I、B、C)
修改存儲器命令:E 有以下幾種命令EB、EC、EI、EL、EF、EP
復雜數據類型顯示:Object命令;用以顯示結構或數組的內容。欲使此命令有效,C51編譯器必須有DB及OBJECTEXTEND兩條。
反匯編命令:U
5. (5) “Watch”表達式之值
在View菜單的“Watch”一欄中有四項:其中包括定義Watch Point(Define)、刪除Watch Point(remove,kill all),及自動更新選項。
也可用WS、WK等命令代替,下面具體看“表達式”類型:
dScope51一次最多可設16個WtchPoint表達式,顯示于Watch Window之中,表達式可以是簡單變量,也可是復雜數據類型如結構、數組和指向結構的指針等,例如:
>WS *ptime
>WS ptime→hour
>WS some_record[o],analog等等
6. (6) 關于.IOF文件
啟動DS51后必須裝入.IOF文件才能使CPU及Peripheral各項起作用,這個函數的使用是依據8051系列CPU的不同特點,裝入8051各CPU硬件設備模擬驅動文件,比如8031CPU就必須load DS51目錄下的8051.IOF。
2. 2. dScope for Windows
dScope for windows具有dScope for dos的全部功能,此外,它還具有以下明顯的優點:
(1) 標準的Windows界面,操作更容易更簡單;
(2) 常用操作多用對話框,而非Dos的行命令方式;
(3) 窗口資源更加豐富:存儲器窗口、覆蓋率分析、運行狀態分析窗口,加強了調試功能;
因為dScope for Windows功能強大,具體操作在第八章詳細介紹。
3. 第三節 Monitor51及其使用
1. 1. Monitor51對硬件的要求
(1) 硬件系統為51系列CPU;
(2) 帶5K外部程序存儲器(從O地址開始),存放Monitor51程序;
(3) 256Bytes的外部數據存儲器以及5K的跟蹤緩沖區,此外,外部數據存儲器必須足夠容納所有應用程序代碼及數據,且所有外部數據存儲器必須為馮·諾伊曼存儲器,即能一致訪問XDATA與Code空間。
(4) 一個定時器作為波特率發生器供串口使用;
(5) 6 Bytes的空余堆棧。
2. 2. Mon51的使用
Mon51的使用途徑有三種方式:
(1) Dos行命令方式
即先用install對MON51進行配置,然后用MON51進入Monitor狀態,啟用各種命令對Monitor51進行調試。
(2) tScope51方式
啟動tScope51裝入TS51目錄下的MON51.IOT驅動文件,與目標板通信。
(3) dScope51 for Windows方式
在選CPU驅動文件時,選“MON51.dll”,則檢查目標板并進入MON51狀態。
3. 3. MON51的配置
(1) MON51 for Dos的配置
運行install文件(在MON51目錄下),不同的參數可以配置不同的硬件環境。INSTALL Serialtype [xdstastart[codestart[bank][PROMCHECK]]],具體說明見MON51幫助文件或使用手冊。
(2) MON51 for Windows的配置
在啟用MON51.dll時,會使得系統自動檢查目標板連接,如配置不對,則彈出“Configuration”對話框,設置PC串口,波特率等,完畢單擊“apply”有效。
4. 4. 串口連接圖:
收發交叉互連,RTS、CTS直連,DSR、DTR直連,具體引腳排列參考串口資料。
5. 5. MON51命令及使用
詳細的MON51命令可參閱幫助。
4. 第四節 集成開發環境(IDE)的使用
1. 1. Ishell for Dos的使用
進入Ishell之后看到兩個窗口:一個是文件窗口,一個是Dos命令行窗口,窗口上方是下拉式的命令菜單,其中的Files控制文件窗口的顯隱。
使用Ishell,第一步就是配置系統,即要學習兩個文件的修改與創建:
1. (1) Ishell.CFG文件
每一個project都有一個Ishell.CFG,其中存放有“Option菜單和Setup菜單下的部分信息;Bell enabled、Monochrome enabled、Editor Selected、CRT Lines、target enviroment、name of user edit、Automatic load for configuration enabled、file window enabled、file specification for file window、translate command line controls、project name等。
對每個project都必須設置以上信息,然后存盤“setup”的的“save”,這樣才可正式開始下面工作。
2. (2) IShell.col文件
對IDE顏色設置,如不改動,可以缺省為主。
3. (3) CDF文件
該文件位于BIN目錄下,每一文件定義一組外部函數工具包,即定義外部環境如8051.CDF,USER.CDF等,開發者可修改CDF文件,供自己使用,至于CDF文件內容可查看一下8051.CDF即可知道。注意.CDF文件是Ishell系統的核心所在,不同的CDF文件可使本IDE適用于不同的編譯、連接系統,即本IDE并不僅適于C51。
下面談一談Automake工具:
C51的Automake是一個project管理器,在8051工具包中以OBJECT文件形式保留了一個project的信息,AutoMake用這些信息來進行project管理,一旦手工建立一個project,Automake可生成一個新的OBJECT,AutoMake利用此文件來編譯那些修改過的文件。
Automake支持C51、A51、L51/BL51、C166、A166、L166等編譯連接器。點中主菜單中的Automake即運行本工具。
Ishell for Dos使用比較繁瑣,推薦使用uVision for windows。
2. 2. uVision for windows的使用
uVision是一個標準的windows應用程序,其編譯功能、文件處理功能、project處理功能、窗口功能以及工具引用功能(如A51、C51、PL/M41、BL51 dScope等)等都較Ishell for Dos要強得多。
uVision采用BL51作連接器,因為BL51兼容L51,所以一切能在Dos下工作的project都可以到uVision中進行連接調試。
uVision采用dScope for windows作調試器,該調試器支持MON51及系統模擬兩種方式,功能較for DOS要強大好用,調試功能強大。
注意:
(1) Option菜單下的各項要會使用,其中A51、C51、PL/M51、BL51定義各文件所使用的編譯、連接控制指令,dScope定義一個dScope初始化文件。Make則是定義一個make文件。
(2) 進入調試是在RUN菜單下運行dScope。
(3) project中包括新建、打開、修改、更新、編譯、連接等poject處理,具體使用可參考后面的例子。
3. 第三章 Keil C51 vs 標準C
深入理解并應用C51對標準ANSIC的擴展是學習C51的關鍵之一。因為大多數擴展功能都是直接針對8051系列CPU硬件的。大致有以下8類:
l 8051存儲類型及存儲區域
l 存儲模式
l 存儲器類型聲明
l 變量類型聲明
l 位變量與位尋址
l 特殊功能寄存器(SFR)
l C51指針
l 函數屬性
具體說明如下(8031為缺省CPU)。
1. 第一節 Keil C51擴展關鍵字
C51 V4.0版本有以下擴展關鍵字(共19個):
_at_ idata sfr16 alien interrupt small
bdata large _task_ Code bit pdata
using reentrant xdata compact sbit data sfr
2. 第二節 內存區域(Memory Areas):
1. 1. Pragram Area:
由Code說明可有多達64kBytes的程序存儲器
2. 2. Internal Data Memory:
內部數據存儲器可用以下關鍵字說明:
data:直接尋址區,為內部RAM的低128字節 00H~7FH
idata:間接尋址區,包括整個內部RAM區 00H~FFH
bdata:可位尋址區, 20H~2FH
3. 3. External Data Memory
外部RAM視使用情況可由以下關鍵字標識:
xdata:可指定多達64KB的外部直接尋址區,地址范圍0000H~0FFFFH
pdata:能訪問1頁(25bBytes)的外部RAM,主要用于緊湊模式(Compact Model)。
4. 4. Speciac Function Register Memory
8051提供128Bytes的SFR尋址區,這區域可位尋址、字節尋址或字尋址,用以控制定時器、計數器、串口、I/O及其它部件,可由以下幾種關鍵字說明:
sfr:字節尋址 比如 sfr P0=0x80;為PO口地址為80H,“=”后H~FFH之間的常數。
sfr16:字尋址,如sfr16 T2=0xcc;指定Timer2口地址T2L=0xcc T2H=0xCD
sbit:位尋址,如sbit EA=0xAF;指定第0xAF位為EA,即中斷允許
還可以有如下定義方法:
sbit 0V=PSW^2;(定義0V為PSW的第2位)
sbit 0V=0XDO^2;(同上)
或bit 0V-=0xD2(同上)。
3. 第三節 存儲模式
存儲模式決定了沒有明確指定存儲類型的變量,函數參數等的缺省存儲區域,共三種:
1. 1. Small模式
所有缺省變量參數均裝入內部RAM,優點是訪問速度快,缺點是空間有限,只適用于小程序。
2. 2. Compact模式
所有缺省變量均位于外部RAM區的一頁(256Bytes),具體哪一頁可由P2口指定,在STARTUP.A51文件中說明,也可用pdata指定,優點是空間較Small為寬裕速度較Small慢,較large要快,是一種中間狀態。
3. 3. large模式
所有缺省變量可放在多達64KB的外部RAM區,優點是空間大,可存變量多,缺點是速度較慢。
提示:存儲模式在C51編譯器選項中選擇。
4. 第四節 存儲類型聲明
變量或參數的存儲類型可由存儲模式指定缺省類型,也可由關鍵字直接聲明指定。各類型分別用:code,data,idata,xdata,pdata說明,例:
data uar1
char code array[ ]=“hello!”;
unsigned char xdata arr[10][4][4];
5. 第五節 變量或數據類型
C51提供以下幾種擴展數據類型:
bit 位變量值為0或1
sbit 從字節中定義的位變量 0或1
sfr sfr字節地址 0~255
sfr16 sfr字地址 0~65535
其余數據類型如:char,enum,short,int,long,float等與ANSI C相同。
6. 第六節 位變量與聲明
1. 1. bit型變量
bit型變量可用變量類型,函數聲明、函數返回值等,存貯于內部RAM20H~2FH。
注意:
(1) 用#pragma disable說明函數和用“usign”指定的函數,不能返回bit值。
(2) 一個bit變量不能聲明為指針,如bit *ptr;是錯誤的
(3) 不能有bit數組如:bit arr[5];錯誤。
2. 2. 可位尋址區說明20H-2FH
可作如下定義:
int bdata i;
char bdata arr[3],
然后:
sbit bito=in0;sbit bit15=I^15;
sbit arr07=arr[0]^7;sbit arr15=arr[i]^7;
7. 第七節 Keil C51指針
C51支持一般指針(Generic Pointer)和存儲器指針(Memory_Specific Pointer).
1. 1. 一般指針
一般指針的聲明和使用均與標準C相同,不過同時還可以說明指針的存儲類型,例如:
long * state;為一個指向long型整數的指針,而state本身則依存儲模式存放。
char * xdata ptr;ptr為一個指向char數據的指針,而ptr本身放于外部RAM區,以上的long,char等指針指向的數據可存放于任何存儲器中。
一般指針本身用3個字節存放,分別為存儲器類型,高位偏移,低位偏移量。
2. 2. 存儲器指針
基于存儲器的指針說明時即指定了存貯類型,例如:
char data * str;str指向data區中char型數據
int xdata * pow; pow指向外部RAM的int型整數。
這種指針存放時,只需一個字節或2個字節就夠了,因為只需存放偏移量。
3. 3. 指針轉換
即指針在上兩種類型之間轉化:
l 當基于存儲器的指針作為一個實參傳遞給需要一般指針的函數時,指針自動轉化。
l 如果不說明外部函數原形,基于存儲器的指針自動轉化為一般指針,導致錯誤,因而請用“#include”說明所有函數原形。
l 可以強行改變指針類型。
8. 第八節 Keil C51函數
C51函數聲明對ANSI C作了擴展,具體包括:
1. 1. 中斷函數聲明:
中斷聲明方法如下:
void serial_ISR () interrupt 4 [using 1]
{
/* ISR */
}
為提高代碼的容錯能力,在沒用到的中斷入口處生成iret語句,定義沒用到的中斷。
/* define not used interrupt, so generate "IRET" in their entrance */
void extern0_ISR() interrupt 0{} /* not used */
void timer0_ISR () interrupt 1{} /* not used */
void extern1_ISR() interrupt 2{} /* not used */
void timer1_ISR () interrupt 3{} /* not used */
void serial_ISR () interrupt 4{} /* not used */
2. 2. 通用存儲工作區
3. 3. 選通用存儲工作區由using x聲明,見上例。
4. 4. 指定存儲模式
由small compact 及large說明,例如:
void fun1(void) small { }
提示:small說明的函數內部變量全部使用內部RAM。關鍵的經常性的耗時的地方可以這樣聲明,以提高運行速度。
5. 5. #pragma disable
在函數前聲明,只對一個函數有效。該函數調用過程中將不可被中斷。
6. 6. 遞歸或可重入函數指定
在主程序和中斷中都可調用的函數,容易產生問題。因為51和PC不同,PC使用堆棧傳遞參數,且靜態變量以外的內部變量都在堆棧中;而51一般使用寄存器傳遞參數,內部變量一般在RAM中,函數重入時會破壞上次調用的數據。可以用以下兩種方法解決函數重入:
a、在相應的函數前使用前述“#pragma disable”聲明,即只允許主程序或中斷之一調用該函數;
b、將該函數說明為可重入的。如下:
void func(param...) reentrant;
KeilC51編譯后將生成一個可重入變量堆棧,然后就可以模擬通過堆棧傳遞變量的方法。
由于一般可重入函數由主程序和中斷調用,所以通常中斷使用與主程序不同的R寄存器組。
另外,對可重入函數,在相應的函數前面加上開關“#pragma noaregs”,以禁止編譯器使用絕對寄存器尋址,可生成不依賴于寄存器組的代碼。
7. 7. 指定PL/M-51函數
由alien指定。
4. 第四章 Keil C51高級編程
本章討論以下內容:
l 絕對地址訪問
l C與匯編的接口
l C51軟件包中的通用文件
l 段名轉換與程序優化
1. 第一節 絕對地址訪問
C51提供了三種訪問絕對地址的方法:
1. 1. 絕對宏:
在程序中,用“#include”即可使用其中定義的宏來訪問絕對地址,包括:
CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD
具體使用可看一看absacc.h便知
例如:
rval=CBYTE[0x0002];指向程序存貯器的0002h地址
rval=XWORD [0x0002];指向外RAM的0004h地址
2. 2. _at_關鍵字
直接在數據定義后加上_at_ const即可,但是注意:
(1)絕對變量不能被初使化;
(2)bit型函數及變量不能用_at_指定。
例如:
idata struct link list _at_ 0x40;指定list結構從40h開始。
xdata char text[25b] _at_0xE000;指定text數組從0E000H開始
提示:如果外部絕對變量是I/O端口等可自行變化數據,需要使用volatile關鍵字進行描述,請參考absacc.h。
3. 3. 連接定位控制
此法是利用連接控制指令code xdata pdata \data bdata對“段”地址進行,如要指定某具體變量地址,則很有局限性,不作詳細討論。
2. 第二節 Keil C51與匯編的接口
1. 1. 模塊內接口
方法是用#pragma語句具體結構是:
#pragma asm
匯編行
#pragma endasm
這種方法實質是通過asm與ndasm告訴C51編譯器中間行不用編譯為匯編行,因而在編譯控制指令中有SRC以控制將這些不用編譯的行存入其中。
2. 2. 模塊間接口
C模塊與匯編模塊的接口較簡單,分別用C51與A51對源文件進行編譯,然后用L51將obj文件連接即可,關鍵問題在于C函數與匯編函數之間的參數傳遞問題,C51中有兩種參數傳遞方法。
(1) 通過寄存器傳遞函數參數
最多只能有3個參數通過寄存器傳遞,規律如下表:
參數數目 char int long,float 一般指針
123 R7R5R3 R6 & R7R4 & R5R2 & R3 R4~R7R4~R7 R1~R3R1~R3R1~R3
(2) 通過固定存儲區傳遞(fixed memory)
這種方法將bit型參數傳給一個存儲段中:
?function_name?BIT
將其它類型參數均傳給下面的段:?function_name?BYTE,且按照預選順序存放。
至于這個固定存儲區本身在何處,則由存儲模式默認。
(3) 函數的返回值
函數返回值一律放于寄存器中,有如下規律:
return type Registev 說明
bit 標志位 由具體標志位返回
char/unsigned char 1_byte指針 R7 單字節由R7返回
int/unsigned int 2_byte指針 R6 & R7 雙字節由R6和R7返回,MSB在R6
long&unsigned long R4~R7 MSB在R4, LSB在R7
float R4~R7 32Bit IEEE格式
一般指針 R1~R3 存儲類型在R3 高位R2 低R1
(4) SRC控制
該控制指令將C文件編譯生成匯編文件(.SRC),該匯編文件可改名后,生成匯編.ASM文件,再用A51進行編譯。
3. 第三節 Keil C51軟件包中的通用文件
在C51\LiB目錄下有幾個C源文件,這幾個C源文件有非常重要的作用,對它們稍事修改,就可以用在自己的專用系統中。
1. 1. 動態內存分配
init_mem.C:此文件是初始化動態內存區的程序源代碼。它可以指定動態內存的位置及大小,只有使用了init_mem( )才可以調回其它函數,諸如malloc calloc,realloc等。
calloc.c:此文件是給數組分配內存的源代碼,它可以指定單位數據類型及該單元數目。
malloc.c:此文件是malloc的源代碼,分配一段固定大小的內存。
realloc.c:此文件是realloc.c源代碼,其功能是調整當前分配動態內存的大小。
2. 2. C51啟動文件STARTUP.A51
啟動文件STARTUP.A51中包含目標板啟動代碼,可在每個project中加入這個文件,只要復位,則該文件立即執行,其功能包括:
l 定義內部RAM大小、外部RAM大小、可重入堆棧位置
l 清除內部、外部或者以此頁為單元的外部存儲器
l 按存儲模式初使化重入堆棧及堆棧指針
l 初始化8051硬件堆棧指針
l 向main( )函數交權
開發人員可修改以下數據從而對系統初始化
常數名 意義
IDATALEN 待清內部RAM長度
XDATA START 指定待清外部RAM起始地址
XDATALEN 待清外部RAM長度
IBPSTACK 是否小模式重入堆棧指針需初始化標志,1為需要。缺省為0
IBPSTACKTOP 指定小模式重入堆棧頂部地址
XBPSTACK 是否大模式重入堆棧指針需初始化標志,缺省為0
XBPSTACKTOP 指定大模式重入堆棧頂部地址
PBPSTACK 是否Compact重入堆棧指針,需初始化標志,缺省為0
PBPSTACKTOP 指定Compact模式重入堆棧頂部地址
PPAGEENABLE P2初始化允許開關
PPAGE 指定P2值
PDATASTART 待清外部RAM頁首址
PDATALEN 待清外部RAM頁長度
提示:如果要初始化P2作為緊湊模式高端地址,必須:PPAGEENAGLE=1,PPAGE為P2值,例如指定某頁1000H-10FFH,則PPAGE=10H,而且連接時必須如下:
L51 PDATA(1080H),其中1080H是1000H-10FFH中的任一個值。
以下是STARTUP.A51代碼片斷,紅色是經常可能需要修改的地方:
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package
; Copyright KEIL ELEKTRONIK GmbH 1990
;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; L51 invocation:
;
; L51 , STARTUP.OBJ
;
;------------------------------------------------------------------------------
;
; User-defined Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; ; the absolute start-address of IDATA memory is always 0
IDATALEN EQU 80H ; the length of IDATA memory in bytes.
;
XDATASTART EQU 0H ; the absolute start-address of XDATA memory
XDATALEN EQU 0H ; the length of XDATA memory in bytes.
;
PDATASTART EQU 0H ; the absolute start-address of PDATA memory
PDATALEN EQU 0H ; the length of PDATA memory in bytes.
;
; Notes: The IDATA space overlaps physically the DATA and BIT areas of the
; 8051 CPU. At minimum the memory space occupied from the C51
; run-time routines must be set to zero.
;------------------------------------------------------------------------------
;
; Reentrant Stack Initilization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; Stack Space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
XBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the COMPACT model.
PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
PBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.
;
;------------------------------------------------------------------------------
;
; Page Definition for Using the Compact Model with 64 KByte xdata RAM
;
; The following EQU statements define the xdata page used for pdata
; variables. The EQU PPAGE must conform with the PPAGE control used
; in the linker invocation.
;
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
PPAGE EQU 0 ; define PPAGE number.
;
;------------------------------------------------------------------------------
3. 3. 標準輸入輸出文件
putchar.c
putchar.c是一個低級字符輸出子程,開發人員可修改后應用到自己的硬件系統上,例如向CLD或LEN輸出字符。
缺省:putchar.c是向串口輸出一個字符XON|XOFF是流控標志,換行符“\*n”自動轉化為回車/換行“\r\n”。
getkey.c
getkey函數是一個低級字符輸入子程,該程序可用到自己硬件系統,如矩陣鍵盤輸入中,缺省時通過串口輸入字符。
4. 4. 其它文件
還包括對Watch-Dog有獨特功能的INIT.A51函數以及對8×C751適用的函數,可參考源代碼。
4. 第四節 段名協定與程序優化
1. 1. 段名協定(Segment Naming Conventions)
C51編譯器生成的目標文件存放于許多段中,這些段是代碼空間或數據空間的一些單元,一個段可以是可重定位的,也可以是絕對段,每一個可重定位的段都有一個類型和名字,C51段名有以下規定:
每個段名包括前綴與模塊名兩部分,前綴表示存儲類型,模塊名則是被編譯的模塊的名字,例如:
?CO?main1 :表示main1模塊中的代碼段中的常數部分
?PR?function1?module 表module模塊中函數function1的可執行段,具體規定參閱手冊。
2. 2. 程序優化
C51編譯器是一個具有優化功能的編譯器,它共提供六級優化功能。確保生成目標代碼的最高效率(代碼最少,運行速度最快)。具體六級優化的內容可參考幫助。
在C51中提供以下編譯控制指令控制代碼優化:
OPTIMIZE(SJXE):盡量采用子程序,使程序代碼減少。
NOAREGS:不使用絕對寄存器訪問,程序代碼與寄存器段獨立。
NOREGPARMS:參數傳遞總是在局部數據段實現,程序代碼與低版本C51兼容。
OPTIMIZE(SIZE)AK OPTIMIZE(speed)提供6級優化功能,缺省為: OPTIMIZE(6,SPEED)。
5. 第五章 Keil C51庫函數參考
C51強大功能及其高效率的重要體現之一在于其豐富的可直接調用的庫函數,多使用庫函數使程序代碼簡單,結構清晰,易于調試和維護,下面介紹C51的庫函數系統。
1. 第一節 本征庫函數(intrinsic routines)和非本征證庫函數
C51提供的本征函數是指編譯時直接將固定的代碼插入當前行,而不是用ACALL和LCALL語句來實現,這樣就大大提供了函數訪問的效率,而非本征函數則必須由ACALL及LCALL調用。
C51的本征庫函數只有9個,數目雖少,但都非常有用,列如下:
_crol_,_cror_:將char型變量循環向左(右)移動指定位數后返回
_iror_,_irol_:將int型變量循環向左(右)移動指定位數后返回
_lrol_,_lror_:將long型變量循環向左(右)移動指定位數后返回
_nop_: 相當于插入NOP
_testbit_: 相當于JBC bitvar測試該位變量并跳轉同時清除。
_chkfloat_: 測試并返回源點數狀態。
使用時,必須包含#inclucle 一行。
如不說明,下面談到的庫函數均指非本征庫函數。
2. 第二節 幾類重要庫函數
1. 1. 專用寄存器include文件
例如8031、8051均為REG51.h其中包括了所有8051的SFR及其位定義,一般系統都必須包括本文件。
2. 2. 絕對地址include文件absacc.h
該文件中實際只定義了幾個宏,以確定各存儲空間的絕對地址。
3. 3. 動態內存分配函數,位于stdlib.h中
4. 4. 緩沖區處理函數位于“string.h”中
其中包括拷貝比較移動等函數如:
memccpy memchr memcmp memcpy memmove memset
這樣很方便地對緩沖區進行處理。
5. 5. 輸入輸出流函數,位于“stdio.h”中
流函數通8051的串口或用戶定義的I/O口讀寫數據,缺省為8051串口,如要修改,比如改為LCD顯示,可修改lib目錄中的getkey.c及putchar.c源文件,然后在庫中替換它們即可。
3. 第三節 Keil C51庫函數原型列表
1. 1. CTYPE.H
bit isalnum(char c);
bit isalpha(char c);
bit iscntrl(char c);
bit isdigit(char c);
bit isgraph(char c);
bit islower(char c);
bit isprint(char c);
bit ispunct(char c);
bit isspace(char c);
bit isupper(char c);
bit isxdigit(char c);
bit toascii(char c);
bit toint(char c);
char tolower(char c);
char __tolower(char c);
char toupper(char c);
char __toupper(char c);
2. 2. INTRINS.H
unsigned char _crol_(unsigned char c,unsigned char b);
unsigned char _cror_(unsigned char c,unsigned char b);
unsigned char _chkfloat_(float ual);
unsigned int _irol_(unsigned int i,unsigned char b);
unsigned int _iror_(unsigned int i,unsigned char b);
unsigned long _irol_(unsigned long l,unsigned char b);
unsigned long _iror_(unsigned long L,unsigned char b);
void _nop_(void);
bit _testbit_(bit b);
3. 3. STDIO.H
char getchar(void);
char _getkey(void);
char *gets(char * string,int len);
int printf(const char * fmtstr[,argument]…);
char putchar(char c);
int puts (const char * string);
int scanf(const char * fmtstr.[,argument]…);
int sprintf(char * buffer,const char *fmtstr[;argument]);
int sscanf(char *buffer,const char * fmtstr[,argument]);
char ungetchar(char c);
void vprintf (const char *fmtstr,char * argptr);
void vsprintf(char *buffer,const char * fmtstr,char * argptr);
4. 4. STDLIB.H
float atof(void * string);
int atoi(void * string);
long atol(void * string);
void * calloc(unsigned int num,unsigned int len);
void free(void xdata *p);
void init_mempool(void *data *p,unsigned int size);
void *malloc (unsigned int size);
int rand(void);
void *realloc (void xdata *p,unsigned int size);
void srand (int seed);
5. 5. STRING.H
void *memccpy (void *dest,void *src,char c,int len);
void *memchr (void *buf,char c,int len);
char memcmp(void *buf1,void *buf2,int len);
void *memcopy (void *dest,void *SRC,int len);
void *memmove (void *dest,void *src,int len);
void *memset (void *buf,char c,int len);
char *strcat (char *dest,char *src);
char *strchr (const char *string,char c);
char strcmp (char *string1,char *string2);
char *strcpy (char *dest,char *src);
int strcspn(char *src,char * set);
int strlen (char *src);
char *strncat (char 8dest,char *src,int len);
char strncmp(char *string1,char *string2,int len);
char strncpy (char *dest,char *src,int len);
char *strpbrk (char *string,char *set);
int strpos (const char *string,char c);
char *strrchr (const char *string,char c);
char *strrpbrk (char *string,char *set);
int strrpos (const char *string,char c);
int strspn(char *string,char *set);
6. 第六章 Keil C51例子:Hello.c
Hello位于\C51\excmples\Hello\目錄,其功能是向串口輸出“Hello,world”整個程序如下:
#pragma DB OE CD
#indule <reg51.h>
#include<stdio.h>
void main(void)
{
SCOn=0x50;
TMOD=0x20
TH1=0xf3;
Tri=1;
TI=1;
printf(“Hello,world \n”);
while(1) { }
}
1. 第一節 uVision for Windows的使用步驟
(1) file_new新建一個hello.c文件,輸入如上內容或直接用目錄下源文件。
(2) file_save或工具欄將文件存盤。
(3) project_new project創建一個project名為hello,并在其中加入hello.c。
這時該project已是打開狀態,或用open project打開已存在的project。
(4) option_C51 compiler中選出至少包括兩項DB OE。
(5) option_dscope Debugger選中hello\DS51.INI
查看DS51.INI看其是否為:
“load…\…\BIN\8051.DLL
map 0, 0xffff”
否則修改。
(6) 在option_make選make文件順序。
(7) project選Build project,看是否有語法錯誤,若無則生成HEX文件,若有則修改源文件后重復以上部分步驟。
(8) run_dScope debugger進入dScope51后裝入hello則可用go直接運行看serial窗口有無輸出,正常每系統運行一次,serial窗口均出現一個“Hello,world”表明運行無誤。
2. 第二節 Ishell for Dos使用步驟
(1) 進入Ishell 用Setup editer選擇編輯器。
然后單擊Edit或用Edit命令編輯hello.c源文件,存盤,也可以在files窗口中直接選中hello.c。
(2) 用cd改換project目錄至hello目錄。
(3) 在setup_target一項目選8051。
(4) 在setup_C51中輸出DB OE。
(5) 在setup_project輸入project名hello。
(6) 在setup_save保存Ishell.CFG文件。
(7) 編輯一個Link文件hello.lin中有“hell.obj”一行。
(8) 由光標落在files菜單中的Hello.c上,單擊“translate”,如無語法錯,再擊“link”,則Hex文件生成。
(9) 單擊Simulate如在8051.CDF中選Simulate為dScope則進入dScope調試直接“Go”,看serial窗口輸出為“Hello.world”。
(10) 如程序有誤修改源代碼后不必再translate或link了,只要一步Amake即可。
若project中包括不止一個文件,在DOS的Ishell中不能用Translate編譯,而應建立bat文件,直接在命令窗編譯,然后link連接。
如還需用Translate則只能多個文件分別編譯,然后連接。
7. 第七章 Keil C51的代碼效率
C51程序編譯生成匯編代碼的效率,是由許多因素共同決定的,對于Keil C51,主要受以下兩種因素影響:
1. 第一節 存儲模式的影響
存儲模式決定了缺省變量的存儲空間,而訪問各空間變量的匯編代碼的繁簡程度決定了代碼率的高低。
例如:一個整形變量i,如放于內存18H、19H空間,則++i的操作編譯成四條語句:
INC 0x19
MOV A,0x19
JNZ 0x272D
INC 0x18
0x272D:
而如果放于外存空間0000H、0001H則++i的操作編譯成九條語句:
MOV DPTR,0001
MOVX A,@ DPTR
INC A
MOVX @ DPTR,A
JNz #5
MOV OPTR,#0000
MOVX A,@DPTR
INC A
MOVX @ DPTR,A
就匯編之后的語句而言,對外部存儲器的操作較內部存儲器操作代碼率要低得多,生成的語句為內存的兩倍以上,而程序中有大量的這種操作,可見存儲模式對代碼率的響了。
因此程序設計的原則是
1、存儲模式從small-Compact-large依次選擇,實在是變量太多,才選large模式。
2、即使選擇了large模式,對一些常用的局部的或者可放于內存中的變量,最好放于內存中,以盡量提高程序的代碼率。
2. 第二節 程序結構的影響
程序的結構單元包括模塊、函數等等。同樣的功能,如果結構越復雜,其所涉及的操作、變量、功能模塊函數等就越多,較之結構性好,代碼簡單的程序其代碼率自然就低得多。
此外程序的運行控制語句,也是影響代碼率的關鍵因素,例如:switch -case語句,許多編譯器都把它們譯得非常復雜,Keil C51也不例外,相對較為簡易的Switch-case語句,編譯成跳轉指令形式,代碼率較高,但對較為復雜的Switch-Case,則要調用一個系統庫函數?C?ICASE進行處理,非常復雜。
再如if( ),while( ),等語句也是代碼相對較低的語句,但編譯以后比switch-case要高得多。
因此建議設計者盡量少用switch-case之類語句來控制程序結構,以提高代碼率。
除以上兩點外,其它因素也會對代碼率產生影響,例如:
是否用寄存器傳遞參數 即NOAREGS選項是否有
是否包括調試信息:即DEBUG選項
是否包括擴展的調試信息:即BJECTEXTEND
8. 第八章 dScope for Windows使用詳解
1. 第一節 概述
1. 1. 主窗口(Mainframe Window)
可設置其它各種調試窗口,設置斷點、觀察點,修改地址空間,加載文件等等;
2. 2. 調試窗口(DEBUG Window)
支持用戶程序的各種顯示方式,可連續運行,單步運行用戶程序,并可在線 匯編;
3. 3. 命令窗口(Command Window)
支持命令行的輸入;
4. 4. 觀察窗口(Watch Window)
可設置所要觀察的變量、表達式等;
5. 5. 寄存器窗口(Registe Window)
顯示內部寄存器的內容,程序運行次數等;
6. 6. 串口窗口(Serical Windows)
顯示串口接收和發送的數據;
7. 7. 性能分析窗口
顯示所要觀察的各程序段占用CPU的空間;
8. 8. 內存窗口(Memory Window)
顯示所選擇的內存中的數據;
9. 9. 符號瀏覽窗口(Symbol Browser Window)
顯示各種符號名稱,包括專有符號,用戶自定義符號(函數名、變量、標號)等;
10. 10. 調用線窗口(Call-Stack Window)
動態顯示當前執行的程序段的函數調用關系;
11. 11. 代碼覆蓋窗口
提供當前模塊內各程序段中被執行代碼的比率;。
12. 12. 外圍設備窗口(peripherals)
可顯示I/O口,定時器,中斷,串口等外圍設備狀態;
2. 第二節 dScope for Windows基本操作
1. 1. 指定初始化文件
在uVision的Option菜單dScope Debugger中指定dScope的初始化文件,用uVision的RUN啟動dScope將自動加載此初始化文件,自動執行其中命令;
下面是一個例子,可以看出調入一個調試代碼的過程。Ds51.ini:
load 8051.dll
load test
slog>>test.log
xtal=11.0592
define button "go to main","g,main"
ws RevCounter
ws rm.r
g,main
PA RESET
PA serial
PA timer0
2. 2. 觀察變量
方法1:命令行
WS expression [, numberbase ] [ LINE ]
其中numberbase為顯示數制,10對應10進制,16對應16進制,缺省為16進制。LINE為單行顯示,缺省為多行顯示。
方法2:setup->Watchpoints,在對話框中輸入變量
3. 3. 顯示RAM的值
d i(x,d):起始地址,終止地址
d 變量名
4. 4. 觀察堆棧
View->Call-stack->Show invocation,可以跟蹤調用過程;
5. 5. 中斷處理程序調試
在裝入8051.dll后,在dScope的主菜單中將增加Peripherial,其有4個字菜單:
I/0 port:Pi端口狀態
Interrupt:中斷設置
Timer:定時器中斷狀態
Serial:串口中斷狀態
設置相應的中斷請求標志位即可產生中斷。
6. 6. 性能分析(Performance Analyzer:PA)
PA用來分析一段代碼執行占用CPU的百分比。定義:
命令行 PA func_name
3. 第三節 dScope for Windows命令文件的編制
dScope除了用命令行的方式進行調試以外,還可將各種調試命令匯集于一個調試文件中,然后調用該文件,就可達到自動測試用戶源代碼的目的。dScope的命令文件支持C/PL/M的格式,因而編制調試命令文件與編制C語言程序有些類似。
1. 1. 地址空間及地址空間類型
1. (1) 地址空間分段
dScope提供的最大可用空間為16M,實際上我們只用以下三段:
① 內部數據空間段(0X00段或D段)
0X00:0X0000~0X00:0XFFFF(對MSC51而言為0X00:0X00FF)
② 外部數據空間段(0X01段式或X段)
0X01:0X0000~0X01~0XFFFF
③ 程序空間段(0XFF段或C段)
0XFF:0X0000~0XFF:0XFFFF
2. (2) 地址空間類型
C:代碼空間
D:內部直接尋址空間
I: 內部間接尋址空間
X:外部數據空間
B:位尋址空間
P:I/O口
EB:擴展的位尋址空間(MCS251專有)
ED:擴展的數據空間(MCS251專有)
CO:常數空間(MCS251專有)
HC:正常數空間(MCS251專有)
2. 2. 常量
dScope支持十六進制、八進制、十進制、二進制常數,其后綴分別為H、Q(O)、T(或無)、Y;
dScope不區分常量的大、小寫。
1. (1) 整型常量
分為整型(int),無符號整型(uint,00rd),長整型(long),無符號長整型(Wlong、Word)。
2. (2) 浮點型常量
與ANSI C相同。
3. (3) 字符串常量
與ANSI C相同
4. (4) 字符常量
分為字符型(Char)和無符號字符型(Uchar)一種。
5. (5) 行號常數
指用戶程序中的行號,實際上是個地址
6. (6) 位常量(Bit):
0和1
7. (7) 地址常數
地址常數的種類很多,地址常數不同于行號常數,行號常數就是一個地址,而地址數被引用時,實際上是取該地址中的數據。
C:代碼地址常數,如C:0X0012或0XFF:0X0012
D:內部直接尋址地址常數,如D:0X0068或0X00:0X0068
I:內部間按尋址地址常數,如I:0X0010或0X00:0X0010
X:外部數據空間地址常數,如X:0X0028或0X01:0X0028
B:位地址常數,如B:0X20或B:0X24.0
EB:擴展的位地址常數(MCS251專有),
ED:擴展的數據空間地址常數(MCS251專有)
CO:常數空間地址常數(MCS251專有)
HC:正常數空間地址常數(MCS251專有)
8. (8) 標識符常量
即用戶源程序中的標號、函數名等,實際上代表某一地址。
9. (9) 用戶源程序中定義的常數
3. 3. 變量
dScope所支持的變量名或標識符最多可由31個字符組成,第一個字母為A~Z,a~z,下劃線或問號,后續字符可為字母、數字、下劃線和問號。除CPU變量和系統變量外,dScope不支持全局變量,但可視“define”命令定義的變量為全局變量。
Dscope所支持的變量分為以下幾種(變量名稱不區分大、小寫),支持類型轉換:
1. (1) 整型變量
分為整型變量(int)、無符號整型變量(uint/word),長整型(Long) 、無符號長整型(Ulong/dword)。
2. (2) 浮點型變量(float)
與ANSI C相同。
3. (3) 字符型變量L
分為字符型(char)變量和無符號字符型(Uchar)
4. (4) 位變量(Bit)
5. (5) 系統變量
dScope自己定義了一系列內部變量,用戶可對這些變量進行讀或讀/寫操作, 可被用戶自定義數所引用。
a. Cycles (Read Only)
32位變量(Ulong),指示當前程序執行已花費的指令周期(cycle)。
b. Ramsize(R/W)
16位變量(Uint),指示內部可直接尋址的數據空間大小。
c. Radix(R/N)
8位變量(Uchar),決定輸出的數制
Radix=0X0A (10進制),Radix=0X10 (16進制)
d. -IIP-(R/W)
8位變量(Uchar),指示當前的中斷嵌套數目。
e. $ (R/W)
32位變量(Ulong),指出PC值,通過對其進行寫操作,可改變程序執行的流程。
f. Itrace (R/W)
8位變量(Uchar),決定是否對程序運行情況進行記錄
Itrace=1,使能記錄操作
Itrace=0,根本上記錄操作
g. __Break__(R/W)
8位變量(Uchar) __Break__=1,中止程序的運行
h. __Mode__和__Frame size__是MCS 251專有的變量。
6. (6) CPU變量
即R0~R7、A、C(位變量)、B、DPTR及特殊功能寄存器變量,對這些變量均可進行讀、寫操作。
7. (7) 用戶源程序中定義的變量、數組、結構等
4. 4. 運算符
dScope支持ANSI C的運算符,包括算術運算符,邏輯運算符,關系運算符。
5. 5. 表達式
以運算符將dScope所支持的常量、變量、函數等連接在一起,就構成了dScope的表達式。
6. 6. 數組
dScope不支持在命令文件中定義數組,但可引用用戶程序中的數組,引用方式如同C。
7. 7. 結構和聯合
dScope不支持在命令文件中定義結構和聯合,但可引用用戶程序中的結構和聯合,引用方式如同C,但如要輸出整個結構或聯合的結果,就要用命令“OBJ”。
8. 8. 指針:
不可自定義指針,但支持用戶源程序中的指針變量。
9. 9. dScope命令語句
dScope提供了一系列調試命令。在命令文件中,dScope只支持這些語句及前述定義的表達式,C語言的語句均不被支持,但在命令文件所包含的用戶自定義函數(非用戶源程序中的函數)中支持C語句,但用戶自定義函數中同樣不支持數組、結構、聯合和指針。
1. (1) ASM
在線匯編命令,格式如下:
ASM C:0Xnnnn (或標號);設定插入匯編指令的地址
ASM 匯編指令
ASM 匯編指令
插入完畢后,在debug窗口內選擇“Assemble->Assemble”完成編譯。
2. (2) Assign
串行口分配指令,格式如下:
Assign channel<unreg>outreg
對MCS51為:Assign Win<SOIN> Soot
但目前的dScope版本并未提供完整串口窗口功能。
3. (3) Define
用戶自定義變量指令,格式如下:
Define <類型> <變量名>
類型一為如前所述的變量類型,Define指令定義的變量可能為全局變量,可為用戶自定義函數所引用。
4. (4) Display
內存顯示命令,格式如下二:
D 起始地址,結束地址
地址如前所述的地址常數,標識符常量。
5. (5) Enter
內存修改指令,格式如下:
E 類型地址=表達式 [表達式2],[……]
類型如前所述,地址如前所述的地址常數。表達式如前所述,但如果是函數名稱(含標號、指針變量),則關鍵字E→EP
6. (6) Map/Reset map
Map為內存段修改指令,Reset map將內存段復位或缺省值。
7. (7) Object
用以引用用戶源程序中的結構(聯合)、數組、格式如下:
Obj表達式 [n,],[Line]
表達式為用戶源程序中的數組,結構(聯合)名稱。當Line缺省時,數目、結構(聯合)的內容按n行輸出;如有Line,則單行輸出。
8. (8) U
反匯編命令,格式如下:
U [地址]
地址包括地址常 數及標識符常量,指明反匯編的起始地址。
9. (9) WK
觀察點刪除命令,格式如下:
WK n1[n2 ],[……] ;刪除指定的觀察點,n為字符型,整型
常數
WK * ;刪除所有的觀察點
10. (10) WS
觀察點設置命令,格式如下:
WS 表達式[,n][LINE]
關鍵字LINE存在時,觀察點表達式單行輸出
LINE缺省時,觀察點表達式n行輸出。
11. (11) G
連續運行命令,格式如下:
G [起始地址],[終止地址]
地址為標識符常量或地址常數,地址缺省時,為連續運行。
12. (12) T/P
單步運行指令,格式如下:
T/P n ;n指至單行運行的步數,P指給用戶當調用某函數時,把它作為一步處理,并不進入該函數運行。
13. (13) PA
性能分析操作指令,其分以下幾種:
PA
顯示當前所設置的性能分析程度段
PA Kill<SPAN style="mso-s