




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、C51中變量和函數(shù)的絕對地址定位問題:1.變量絕對地址定位1)在定義變量時使用_at_關鍵字加上地址就可.e.g.unsigned char idata myvar _at_ 0x40;把變量myvar定義在idata的0x40處,在M51文件中可以找到這麼一行IDATA0040H0001HABSOLUTE表示有變量在idata的0x0040處絕對地址定位.2)使用KeilC編譯器定義絕對地址的變量,方法待查.2.函數(shù)絕對地址定位1)在程序中編寫一函數(shù)myTestvoid myTest(void)/ Add your code here2)使用KeilC編譯器定位絕對地址的函數(shù),打開Proje
2、ct - Options for Target菜單,選中BL51 Locate選項卡,在Code:中輸入:?PR?myTest?MAIN(0x4000)把函數(shù)myTest定位到程序區(qū)的0x4000處,再次編譯就可以了.3)一次定位多個函數(shù)的方法同樣地,在程序中再編寫另外一個函數(shù)myTest1void myTest1(void)/ Add your code here在Options for Target菜單的BL51 Locate選項卡的Code:中輸入:?PR?myTest1?MAIN(0x3900), ?PR?myTest?MAIN(0x4000)把函數(shù)myTest1定位在程序區(qū)的0x39
3、00處,把函數(shù)myTest定義在程序區(qū)的0x4000處,重新編譯就可以了.在M51文件中可以找到下面的內容: 3.obj TO Reader RAMSIZE (256) CODE (?PR?MYTEST1?MAIN (0X3900), ?PR?MYTEST?MAIN(0X4000)3665H029BH* GAP *CODE3900H0014HUNIT?PR?MYTEST1?MAIN3914H06ECH* GAP *CODE4000H0014HUNIT?PR?MYTEST?MAIN4)函數(shù)的調用:程序中直接調用函數(shù)的方式就不說明了,這里重點講使用函數(shù)指針調用絕對地址處的函數(shù)的方法.(1)定義調用
4、的函數(shù)原形typedef void (*CALL_MYTEST)(void);這是一個回調函數(shù)的原形,參數(shù)為空.(2)定義相應的函數(shù)指針變量CALL_MYTESTmyTestCall = NULL;(3)函數(shù)指針變量賦值,指向我們定位的絕對地址的函數(shù)myTestCall = 0x3900;指向函數(shù)myTest1(4)函數(shù)指針調用if (myTestCall != NULL)myTestCall();/調用函數(shù)指針處的函數(shù)myTest1,置PC指針為0x3900檢查編譯生成的bin文件,到0x3900處可以看到myTest1的內容,在0x4000處可以看到myTest的內容,(5)其它說明:如果
5、在0x3000到0x3900的程序空間沒有內容時,把myTestCall的地址指針指到0x3800(在0x3000到0x3900之間)時,會從0x3900處開始執(zhí)行.至於在Load中調用AP中的函數(shù)的方法與此類似,但是相應的參數(shù)傳遞可能要另尋方法.*keil C51絕對地址訪問在利用keil進行8051單片機編程的時,常常需要進行絕對地址進行訪問.特別是對硬件操作,如DA AD采樣,LCD液晶操作,打印操作.等等.C51提供了三種訪問絕對地址的方法:1.絕對宏:在程序中,用“include”即可使用其中定義的宏來訪問絕對地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、X
6、WORD、PBYTE、DWORD具體使用可看一看absacc.h便知例如:rval=CBYTE0x0002;指向程序存貯器的0002h地址rval=XWORD 0x0002;指向外RAM的0004h地址2. _at_關鍵字直接在數(shù)據(jù)定義后加上_at_ const即可,但是注意:(1)絕對變量不能被初使化;(2)bit型函數(shù)及變量不能用_at_指定。例如:idata struct link list _at_ 0x40;指定list結構從40h開始。xdata char text25b _at_0xE000;指定text數(shù)組從0E000H開始提示:如果外部絕對變量是I/O端口等可自行變化數(shù)據(jù),需
7、要使用volatile關鍵字進行描述,請參考absacc.h。3.連接定位控制此法是利用連接控制指令code xdata pdata data bdata對“段”地址進行,如要指定某具體變量地址,則很有局限性,不作詳細討論。附:(c51)/*- ABSACC.H Direct access to 8051, extended 8051 and Philips 80C51MX memory areas. Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved. -*/ #if
8、ndef _ABSACC_H_ #define _ABSACC_H_ #define CBYTE (unsigned char volatile code *) 0) #define DBYTE (unsigned char volatile data *) 0) #define PBYTE (unsigned char volatile pdata *) 0) #define XBYTE (unsigned char volatile xdata *) 0) #define CWORD (unsigned int volatile code *) 0) #define DWORD (unsi
9、gned int volatile data *) 0) #define PWORD (unsigned int volatile pdata *) 0) #define XWORD (unsigned int volatile xdata *) 0) #ifdef _CX51_ #define FVAR(object, addr) (*(object volatile far *) (addr) #define FARRAY(object, base) (object volatile far *) (base) #define FCVAR(object, addr) (*(object c
10、onst far *) (addr) #define FCARRAY(object, base) (object const far *) (base) #else #define FVAR(object, addr) (*(object volatile far *) (addr)+0x10000L) #define FCVAR(object, addr) (*(object const far *) (addr)+0x810000L) #define FARRAY(object, base) (object volatile far *) (base)+0x10000L) #define
11、FCARRAY(object, base) (object const far *) (base)+0x810000L) #endif #endif 附:(c166) /*- ABSACC.H Direct access to 166 memory areas for C166/EC+ Version 5. Copyright (c) 1992-2004 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved. -*/ #ifndef _ABSACC_H_ #define _ABSACC_H_ #if (_MODEL_
12、= 0) #define MVAR(object, addr) (*(object volatile *) (addr) #define MARRAY(object, base) (object volatile *) (base) #else #define MVAR(object, addr) (*(object volatile far *) (addr) #define MARRAY(object, base) (object volatile far *) (base) #define HVAR(object, addr) (*(object volatile huge *) (ad
13、dr) #define HARRAY(object, base) (object volatile huge *) (base) #define XVAR(object, addr) (*(object volatile xhuge *) (addr) #define XARRAY(object, base) (object volatile xhuge *) (base) #endif #endif以下來自轉載:使用KeilC51軟件,可以很方便地將代碼或者數(shù)據(jù)絕對定位到某個地址。1、代碼定位:方法1:使用偽指令CSEG。比如要將MyFunc1定位到代碼區(qū)C:0x1000,則新建一個A51文
14、件,添加以下內容:PUBLIC MYFUNC1CSEG AT 1000HMYFUNC1:;其它代碼RET在其它源文件中,就可以調用MyFunc()函數(shù)了。需要注意的是,編譯器不檢測傳遞參數(shù)的數(shù)目,僅檢測函數(shù)是否有返回值。方法2:使用BL51 Locate選項。比如在main.c中定義了一個MyFunc2函數(shù),并且要將該函數(shù)定位到代碼區(qū)C:0x2000,則從菜單中選擇Project-Options for Target Target1,在彈出的對話框中選擇BL51 Locate頁,在下面的code欄中寫上?PR?MYFUNC2?MAIN(0x2000)即可。如果想定位多個函數(shù),也可以使用*通配符
15、。2、變量定位:只有全局變量可以絕對定位,局部變量無法實現(xiàn)絕對定位。方法1:使用_at_關鍵字。聲明一個全局變量unsigned char data MyBuf18 _at_ 0x20;方法2:使用BL51 Locate選項。比如將main.c中定義的所有data型的全局變量定位到數(shù)據(jù)區(qū)D:0x28開始的空間,則從菜單中選擇Project-Options for Target Target1,在彈出的對話框中選擇BL51 Locate頁,在下面的data欄中寫上?DT?MAIN(0x28)即可。如果是idata,則使用?ID?MAIN(0x28),如果是xdata,則使用?XD?MAIN(0x
16、28),如果是pdata,則使用?PD?MAIN(0x28)3、堆棧定位:在STARTUP.A51文件中定義了堆棧區(qū)?STACK,其起始地址同樣可以在BL51 Locate頁中設置,在Stack欄寫上?STACK(0x80)BL51 locate選項卡中code range和xdata range如果不填寫,編譯默認將程序中相應代碼和變量從空間前面取起網(wǎng)上看到有人提到在keil中使用_at_進行絕對地址定位問題,我簡單介紹一下它的用法。使用_at_關鍵字對存儲器進行絕對地址定位程序如下i ncludechar xdata LED_Data50 _at_ 0x8000;main()LED_Dat
17、a0 = 0x23;在keil中運行以上程序可以在存儲器窗口中輸入x:0x8000可以看到0x8000地址中的值為0x23.值得指出的幾點是1.在給變量LED_Data50定位絕對地址空間時,不能對其賦初值。2.char xdata LED_Data50 _at_ 0x8000;這條語句不能主函數(shù)中。有些網(wǎng)友提到在按著keil說明中用_at_進行絕對地址定位時,編譯會出現(xiàn)錯誤274,就是將這條語句放在主函數(shù)中的原因。3.keil中地址是自動分配的,所以除非特殊情況否則不提倡使用絕對地址定位。初學者因帖別注意。不要把c當作匯編使用。對需要/RST復位后要保持變量不變,防止意外改變(比如升級到新程
18、序,變量地址可能被編譯器優(yōu)化到其他地方),比較有用!STARTUP.A51這個文件有什么用,有必要添加到工程嗎?如果不添加startup.a51文件,編譯器就會自動加入一段初始化內存以及堆棧等的代碼,這時的內存初始化部分你就無法去控制了,當然這在大部分情況下沒什么關系。但是如果你想你的程序在復位后,內存里面的信息依然還保存著(所說的“熱復位”),那么你就需要添加該啟動文件,并且去里面修改內存初始化部分,不要初始化你需要保留的部分內存。請問如何在keil編譯器里,編程時指定函數(shù)的絕對地址(無內容)不好意思啊,我還從來沒有接觸過有這樣要求情況,不過從網(wǎng)上其他地方找了一篇你參考一下吧,、函數(shù)定位:假
19、如要把C源文件tools.c中的函數(shù)int BIN2HEX(int xx).放在CODE MEMORY的0x1000處,先編譯該工程,然后打開該工程的M51文件,在* * * C O D E M E M O R Y * * *行下找出要定位的函數(shù)的名稱,應該形如:CODE xxxxH xxxxH UNIT ?PR?_BCD2HEX?TOOLS然后在:Project-Options for Target .-BL51 Locate:Code中填寫如下內容:?PR?_BCD2HEX?TOOLS(0x1000)再次Build,在M51中會發(fā)現(xiàn)該函數(shù)已放在CODE MEMORY的0x1000處了2、賦
20、初值的變量定位:要將某變量定位在一絕對位置且要賦初值,此時用_at_不能完成,則如下操作:在工程中建立一個新的文件,如InitVars.c,在其中對要處理的變量賦初值(假設是code變量):char code myVer = COPYRIGHT 2001-11;然后將該文件加入工程,編譯,打開M51文件,若定義的是code型,則在* * * C O D E M E M O R Y * * *下可找到:CODE xxxxH xxxxH UNIT ?CO?INITVARS然后在:Project-Options for Target .-BL51 Locate:Code中填入:?CO?INITVAR
21、S(0x200)再次編譯即可。相應地,如為xdata變量,則InitVars.c中寫:char xdata myVer = COPYRIGHT 2001-11;然后將該文件加入工程,編譯,打開M51文件,在* * *X D A T A M E M O R Y* * *下可找到:XDATA xxxxH xxxxH UNIT ?XD?INITVARS然后在:Project-Options for Target .-BL51 Locate:Xdata中填入:?XD?INITVARS(0x200)再次編譯即可。相應地,若定義的是data/idata等變量,則相應處理即可。3、若有多個變量或函數(shù)要進行絕
22、對地址定位,則應按地址從低到高的順序排列。*PIC 51混編C18指定數(shù)據(jù)絕對地址51:RSEG是段選擇指令,要想明白它的意思就要了解段的意思。段是程序代碼或數(shù)據(jù)對象的存儲單位。程序代碼放到代碼段,數(shù)據(jù)對象放到數(shù)據(jù)段。段分兩種,一是絕對段,一是再定位段。絕對段在匯編語言中指定,在用L51聯(lián)接的時候,地址不會改變。用于如訪問一個固定存儲器的i/o,或提供中斷向量的入口地址。而再定位段的地址是浮動的。它的地址有L51對程序模塊連接時決定,C51對源程序編譯所產(chǎn)生的段都是再定位段,它都有段名和存儲類型。絕對段沒有段名。說了這么多,大家可能還是不明白段是什么意思。別急,接著往下看。例如,你寫用C寫了一
23、個函數(shù)void test_fun(void) ,存在test.c中,用編譯器編譯以后. SRC FILE中看到:?PR?test_fun?TEST SEGMENT CODE /(函數(shù)放到代碼段中)寫這個函數(shù)體的時候: RSEG ?PR?test_fun?TEST /選擇已定位的代碼段為當前段test_fun:/代碼所以函數(shù)的表達模式是這樣:?PR?函數(shù)名?文件名而函數(shù)名又分: 1:無參函數(shù)?PR?函數(shù)名?文件名2:有參函數(shù)?PR?_函數(shù)名?文件名3:再入函數(shù)?PR?_?函數(shù)名?文件名又例如你定義了全局變量unsigned char data temp1,temp2; unsigned char
24、 xdata temp3;在test.c文件中,編譯器會為每個文件分0到多個全局數(shù)據(jù)段,相同類型的全局變量被存到同一段中。所以上面會編譯成如下:RSEG ? DT? TEST. temp1: DS 1. temp2: DS 1;RSEG ?XD? TEST. temp3: DS 1/下面是各個類型的數(shù)據(jù)全局段的表示?CO?文件名/常數(shù)段?XD? FILE_NAME /XDATA數(shù)據(jù)段?DT? FILE_NAME /DATA數(shù)據(jù)段?ID? FILE_NAME /IDATA.?BI? FILE_NAME / BIT .?BA? FILE_NAME /BDATA.?PD? FILE_NAME /PD
25、ATA.看到這里大家應該明白段的意思了吧。也許你會問,這有什么作用哪?它就是用在當你需要用匯編語言寫一部份程序的時候,把匯編寫的函數(shù)放在這個問件中,改名xxx.a51,按上面的規(guī)則寫。編譯就好。既然知道了段的意思,現(xiàn)在我們回到SEG的用法上來。A51中有兩種段選擇指令:再定位段選擇指令和絕對段選擇指令.它們用來選擇當前段是再定位段還是絕對段。使用不同的段選擇指令,將使程序定位在不同的地址空間之內。1:再定位段的選擇指令是:RSEG段名它用來選擇一個在前面已經(jīng)定義過的再定位段作為當前段。用法就像我們上面的例子,先申明了一個函數(shù)段,后面寫這個函數(shù)段。2:絕對段選擇指令CSEG AT絕對地址表達式
26、/絕對代碼段DSEG AT絕對地址表達式 /內部絕對數(shù)據(jù)段XSEG AT絕對地址表達式 /外部絕對數(shù)據(jù)段ISEG AT絕對地址表達式 /內部間接尋址絕對數(shù)據(jù)段BSEG AT絕對地址表達式 /絕對位尋址段它們的用法我舉一個例子:例如我們寫串口中斷程序,起始地址是0x23.就這樣寫CSEG AT 0X23LJMP serialISRRSEG ?PR?serialISR?TEST. serialISR:PIC:匯編函數(shù)使用同一個工程C文件中的變量,例如ICFLAG在C文件中定義,則匯編文件中定義方式為;定義外部變量EXTERN ICFLAG定義函數(shù)例如CARDATR:.RETGLOBAL CARDA
27、TR在同一個工程文件下調用匯編中的函數(shù)CARDATR則應該定義函數(shù)extern void CARDATR(void);C18指定數(shù)據(jù)絕對地址例如:#pragma udata overlay RECBUFS =0x190 /200UINT8 NUMBER;UINT8 REC_BUF31;#pragma udata*8標簽:KEILC51編程KEIL C51高級編程KEIL C51高級編程第一節(jié)絕對地址訪問C51提供了三種訪問絕對地址的方法:1.絕對宏:在程序中,用“include”即可使用其中定義的宏來訪問絕對地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、P
28、BYTE、DWORD具體使用可看一看absacc.h便知例如:rval=CBYTE0x0002;指向程序存貯器的0002h地址rval=XWORD 0x0002;指向外RAM的0004h地址2. _at_關鍵字直接在數(shù)據(jù)定義后加上_at_ const即可,但是注意:(1)絕對變量不能被初使化;(2)bit型函數(shù)及變量不能用_at_指定。例如:idata struct link list _at_ 0x40;指定list結構從40h開始。xdata char text25b _at_0xE000;指定text數(shù)組從0E000H開始提示:如果外部絕對變量是I/O端口等可自行變化數(shù)據(jù),需要使用vol
29、atile關鍵字進行描述,請參考absacc.h。3.連接定位控制此法是利用連接控制指令code xdata pdata data bdata對“段”地址進行,如要指定某具體變量地址,則很有局限性,不作詳細討論。第二節(jié)Keil C51與匯編的接口1.模塊內接口方法是用pragma語句具體結構是:#pragma asm匯編行#pragma endasm這種方法實質是通過asm與ndasm告訴C51編譯器中間行不用編譯為匯編行,因而在編譯控制指令中有SRC以控制將這些不用編譯的行存入其中。2.模塊間接口C模塊與匯編模塊的接口較簡單,分別用C51與A51對源文件進行編譯,然后用L51將obj文件連接
30、即可,關鍵問題在于C函數(shù)與匯編函數(shù)之間的參數(shù)傳遞問題,C51中有兩種參數(shù)傳遞方法。(1)通過寄存器傳遞函數(shù)參數(shù)最多只能有3個參數(shù)通過寄存器傳遞,規(guī)律如下表:參數(shù)數(shù)目charintlong,float一般指針123R7R5R3R6 & R7R4 & R5R2 & R3R4R7R4R7R1R3R1R3R1R3(2)通過固定存儲區(qū)傳遞(fixed memory)這種方法將bit型參數(shù)傳給一個存儲段中:?function_name?BIT將其它類型參數(shù)均傳給下面的段:?function_name?BYTE,且按照預選順序存放。至于這個固定存儲區(qū)本身在何處,則由存儲模式默認。(3)函數(shù)的返回值函數(shù)返回值
31、一律放于寄存器中,有如下規(guī)律:return typeRegistev說明bit標志位由具體標志位返回char/unsigned char 1_byte指針R7單字節(jié)由R7返回int/unsigned int 2_byte指針R6 & R7雙字節(jié)由R6和R7返回,MSB在R6long&unsigned longR4R7MSB在R4, LSB在R7floatR4R732Bit IEEE格式一般指針R1R3存儲類型在R3高位R2低R1(4) SRC控制該控制指令將C文件編譯生成匯編文件(.SRC),該匯編文件可改名后,生成匯編.ASM文件,再用A51進行編譯。第三節(jié)Keil C51軟件包中的通用文件
32、在C51LiB目錄下有幾個C源文件,這幾個C源文件有非常重要的作用,對它們稍事修改,就可以用在自己的專用系統(tǒng)中。1.動態(tài)內存分配init_mem.C:此文件是初始化動態(tài)內存區(qū)的程序源代碼。它可以指定動態(tài)內存的位置及大小,只有使用了init_mem( )才可以調回其它函數(shù),諸如malloc calloc,realloc等。calloc.c:此文件是給數(shù)組分配內存的源代碼,它可以指定單位數(shù)據(jù)類型及該單元數(shù)目。malloc.c:此文件是malloc的源代碼,分配一段固定大小的內存。realloc.c:此文件是realloc.c源代碼,其功能是調整當前分配動態(tài)內存的大小。2. C51啟動文件START
33、UP.A51啟動文件STARTUP.A51中包含目標板啟動代碼,可在每個project中加入這個文件,只要復位,則該文件立即執(zhí)行,其功能包括:l定義內部RAM大小、外部RAM大小、可重入堆棧位置l清除內部、外部或者以此頁為單元的外部存儲器l按存儲模式初使化重入堆棧及堆棧指針l初始化8051硬件堆棧指針l向main( )函數(shù)交權開發(fā)人員可修改以下數(shù)據(jù)從而對系統(tǒng)初始化常數(shù)名意義IDATALEN待清內部RAM長度XDATA START指定待清外部RAM起始地址XDATALEN待清外部RAM長度IBPSTACK是否小模式重入堆棧指針需初始化標志,1為需要。缺省為0IBPSTACKTOP指定小模式重入堆
34、棧頂部地址XBPSTACK是否大模式重入堆棧指針需初始化標志,缺省為0XBPSTACKTOP指定大模式重入堆棧頂部地址PBPSTACK是否Compact重入堆棧指針,需初始化標志,缺省為0PBPSTACKTOP指定Compact模式重入堆棧頂部地址PPAGEENABLE P2初始化允許開關PPAGE指定P2值PDATASTART待清外部RAM頁首址PDATALEN待清外部RAM頁長度提示:如果要初始化P2作為緊湊模式高端地址,必須:PPAGEENAGLE1,PPAGE為P2值,例如指定某頁1000H10FFH,則PPAGE10H,而且連接時必須如下:L51PDATA(1080H),其中1080
35、H是1000H10FFH中的任一個值。以下是STARTUP.A51代碼片斷,紅色是經(jīng)??赡苄枰薷牡牡胤剑?-; 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 modifi
36、ed 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
37、0IDATALEN EQU 80H ; the length of IDATA memory in bytes.;XDATASTART EQU 0H ; the absolute start-address of XDATA memoryXDATALEN EQU 0H ; the length of XDATA memory in bytes.;PDATASTART EQU 0H ; the absolute start-address of PDATA memoryPDATALEN EQU 0H ; the length of PDATA memory in bytes.; Notes: T
38、he 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:;
39、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 0F
40、FFFH+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; T
41、he 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.標準輸入輸出文件putchar.cputchar.c是一個低級字符輸出子程,開發(fā)人員可修改后應用到
42、自己的硬件系統(tǒng)上,例如向CLD或LEN輸出字符。缺?。簆utchar.c是向串口輸出一個字符XON|XOFF是流控標志,換行符“*n”自動轉化為回車/換行“rn”。getkey.cgetkey函數(shù)是一個低級字符輸入子程,該程序可用到自己硬件系統(tǒng),如矩陣鍵盤輸入中,缺省時通過串口輸入字符。4.其它文件還包括對Watch-Dog有獨特功能的INIT.A51函數(shù)以及對8C751適用的函數(shù),可參考源代碼。第四節(jié)段名協(xié)定與程序優(yōu)化1.段名協(xié)定(Segment Naming Conventions)C51編譯器生成的目標文件存放于許多段中,這些段是代碼空間或數(shù)據(jù)空間的一些單元,一個段可以是可重定位的,也可
43、以是絕對段,每一個可重定位的段都有一個類型和名字,C51段名有以下規(guī)定:每個段名包括前綴與模塊名兩部分,前綴表示存儲類型,模塊名則是被編譯的模塊的名字,例如:?CO?main1:表示main1模塊中的代碼段中的常數(shù)部分?PR?function1?module表module模塊中函數(shù)function1的可執(zhí)行段,具體規(guī)定參閱手冊。2.程序優(yōu)化C51編譯器是一個具有優(yōu)化功能的編譯器,它共提供六級優(yōu)化功能。確保生成目標代碼的最高效率(代碼最少,運行速度最快)。具體六級優(yōu)化的內容可參考幫助。在C51中提供以下編譯控制指令控制代碼優(yōu)化:OPTIMIZE(SJXE):盡量采用子程序,使程序代碼減少。NOA
44、REGS:不使用絕對寄存器訪問,程序代碼與寄存器段獨立。NOREGPARMS:參數(shù)傳遞總是在局部數(shù)據(jù)段實現(xiàn),程序代碼與低版本C51兼容。OPTIMIZE(SIZE)AK OPTIMIZE(speed)提供6級優(yōu)化功能,缺省為:OPTIMIZE(6,SPEED)。第五節(jié)KeilC51的代碼效率一、存儲模式的影響存儲模式?jīng)Q定了缺省變量的存儲空間,而訪問各空間變量的匯編代碼的繁簡程度決定了代碼率的高低。例如:一個整形變量i,如放于內存18H、19H空間,則+i的操作編譯成四條語句:INC 0x19MOV A,0x19JNZ 0x272DINC 0x180x272D:而如果放于外存空間0000H、00
45、01H則+i的操作編譯成九條語句:MOV DPTR,0001MOVX A, DPTRINC AMOVX DPTR,AJNz #5MOV OPTR,#0000MOVX A,DPTRINC AMOVX DPTR,A就匯編之后的語句而言,對外部存儲器的操作較內部存儲器操作代碼率要低得多,生成的語句為內存的兩倍以上,而程序中有大量的這種操作,可見存儲模式對代碼率的響了。因此程序設計的原則是1、存儲模式從small-Compact-large依次選擇,實在是變量太多,才選large模式。2、即使選擇了large模式,對一些常用的局部的或者可放于內存中的變量,最好放于內存中,以盡量提高程序的代碼率。二、程
46、序結構的影響程序的結構單元包括模塊、函數(shù)等等。同樣的功能,如果結構越復雜,其所涉及的操作、變量、功能模塊函數(shù)等就越多,較之結構性好,代碼簡單的程序其代碼率自然就低得多。此外程序的運行控制語句,也是影響代碼率的關鍵因素,例如:switch -case語句,許多編譯器都把它們譯得非常復雜,Keil C51也不例外,相對較為簡易的Switch-case語句,編譯成跳轉指令形式,代碼率較高,但對較為復雜的Switch-Case,則要調用一個系統(tǒng)庫函數(shù)?C?ICASE進行處理,非常復雜。再如if( ),while( ),等語句也是代碼相對較低的語句,但編譯以后比switch-case要高得多。因此建議設
47、計者盡量少用switch-case之類語句來控制程序結構,以提高代碼率。除以上兩點外,其它因素也會對代碼率產(chǎn)生影響,例如:是否用寄存器傳遞參數(shù)即NOAREGS選項是否有是否包括調試信息:即DEBUG選項是否包括擴展的調試信息:即BJECTEXTEND第六節(jié)如何優(yōu)化C語言代碼(程序員必讀)1、選擇合適的算法和數(shù)據(jù)結構應該熟悉算法語言,知道各種算法的優(yōu)缺點,具體資料請參見相應的參考資料,有很多計算機書籍上都有介紹。將比較慢的順序查找法用較快的二分查找或亂序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序執(zhí)行的效率。.選擇一種合適的數(shù)據(jù)結構也很重要,比如你在一堆隨機存放的數(shù)中使用了大量的插入和刪除指令,那使用鏈表要快得多。數(shù)組與指針語句具有十分密碼的關系,一般來說,指針比較靈活簡潔,而數(shù)組則比較直觀,容易理解。對于大部分的編譯器,使用指針比使用數(shù)組生成的代碼更短,執(zhí)行效率更高。但是在Keil中則相反,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 監(jiān)測施工方案
- 二零二五年度工傷事故賠償補償爭議解決協(xié)議
- 二零二五年度新能源汽車買賣合同分期付款協(xié)議
- 二零二五年度魚塘承包與漁業(yè)多元化經(jīng)營合作協(xié)議
- 二零二五年度新能源研發(fā)合作合伙人協(xié)議書
- 2025年度退房協(xié)議書規(guī)范范本
- 二零二五年度新型購物積分制合作協(xié)議合同
- 二零二五年度房屋租賃市場租金評估合同
- 2025年度離婚子女撫養(yǎng)權及財產(chǎn)分割協(xié)議書
- 二零二五年度定制木門研發(fā)創(chuàng)新與技術轉移合同
- 會計科研方法與研究前沿
- 人工智能對日常生活的影響
- 隨機過程與數(shù)學金融
- (應用詳盡版)純人工勞務分包簡單的合同(通用)
- 民事抗訴申請書(參考范文)
- 《汽車油料與維護》課件
- 《有限元基礎》課件
- 2024年中國鐵路南寧局集團招聘筆試參考題庫含答案解析
- 《3D打印技術》課程標準2
- 第三章稻谷碾米
- 中小學教師評課評價量表
評論
0/150
提交評論