色爱av综合网_色女人在线视频_男男gaygays亚洲_日本高清久久一区二区三区

購物車0種商品
IC郵購網(wǎng)-IC電子元件采購商城
深入淺出: C 與 C++ 中“結(jié)構(gòu)直接復(fù)制”的探討
(2011/10/25 9:27:00)

結(jié)構(gòu)直接復(fù)制在 c 語言中使用的不多, 但在 c++ 卻是一個熱門,幾乎每一本書,幾乎每一個 c++ 程序員的面試都不可避免的提到結(jié)構(gòu)直接復(fù)制的問題。我們現(xiàn)在來探討結(jié)構(gòu)直接復(fù)制在 c 與 c++ 有什么異同,先來看看一段簡單的程序:



    typedef struct SA
    {
    char x;
    } A;

    void main (void) {
    A a1, a2;
    a1 = a2;
    }
復(fù)制代碼


其中的 a1 = a2, 就是結(jié)構(gòu)直接復(fù)制, 在 c 中,這種方法優(yōu)劣如何呢?來看看Keil C 生成的匯編代碼:



    14: a1 = a2;
    C:0x0D07 7808 MOV R0,#0x08
    C:0x0D09 7C00 MOV R4,#0x00
    C:0x0D0B 7D00 MOV R5,#0x00
    C:0x0D0D 7B00 MOV R3,#0x00
    C:0x0D0F 7A00 MOV R2,#0x00
    C:0x0D11 7909 MOV R1,#0x09
    C:0x0D13 7E00 MOV R6,#0x00
    C:0x0D15 7F01 MOV R7,#0x01
    C:0x0D17 120C2C LCALL C?COPY(C:0C2C)
復(fù)制代碼
可以看到,僅僅一個字節(jié)的復(fù)制,竟然使用了大量的代碼,效率及其低下。而這段代碼與Keil C 中 memcpy 是一模一樣的:




    15: memcpy(&a1, &a2, sizeof(A));
    C:0x0CF3 7808 MOV R0,#0x08
    C:0x0CF5 7C00 MOV R4,#0x00
    C:0x0CF7 7D00 MOV R5,#0x00
    C:0x0CF9 7B00 MOV R3,#0x00
    C:0x0CFB 7A00 MOV R2,#0x00
    C:0x0CFD 7909 MOV R1,#0x09
    C:0x0CFF 7E00 MOV R6,#0x00
    C:0x0D01 7F01 MOV R7,#0x01
    C:0x0D03 120C2C LCALL C?COPY(C:0C2C)
復(fù)制代碼
這就是說,Keil C 中”結(jié)構(gòu)直接復(fù)制” 簡單的調(diào)用了 memcpy。 而 8051 既沒有 DMA, 也沒有 block move/copy 之類的復(fù)制指令,因此 memcpy 的效率不會很高。


現(xiàn)在我們來看看 C++ 下面的表現(xiàn),編譯器使用 Borland C++, 同樣的代碼,Borland c++ 顯然聰明了很多,僅僅生成了兩條 8086 匯編指令:
cs:026D 8A46FC mov al,[bp-04]
cs:0270 8846F8mov [bp-08],al

非常精簡。 這樣,沒有什么比較性。我們現(xiàn)在稍微修改一下
typedef struct SA
{

char x[3];
} A;

此時,Borland C++ 同樣生成了一大堆的代碼:




    #TEST2#13:a1 = a2;
    cs:026D 8D46FC lea ax,[bp-04]
    cs:0270 16 push ss
    cs:0271 50 push ax
    cs:0272 8D46F8 lea ax,[bp-08]
    cs:0275 16 push ss
    cs:0276 50 push ax
    cs:0277 B90300 mov cx,0003
    cs:027A E8D31E call N_SCOPY@
復(fù)制代碼



我們可以得出一個結(jié)論,borland c++
下”結(jié)構(gòu)直接復(fù)制” 的效率也不過如此。





等等!結(jié)構(gòu)(類)直接復(fù)制在 c++ 里大量的使用,難道沒有一個更好的方法來實(shí)現(xiàn)么?比如:



a1.x[0] = a2.x[0];



a1.x[1] = a2.x[1];



a1.x[2] = a2.x[2];



或者,程序員只想復(fù)制其中一部分的數(shù)據(jù),而不是像在 c 下用memcpy 全部復(fù)制?C++ 下有什么樣的方法可以實(shí)現(xiàn)呢?




網(wǎng)友評論:回答劉工 9 樓的問題:

復(fù)制一個10,000字節(jié)的結(jié)構(gòu)或者文件!
自己寫for還是while ?不用,a1=a2; 一分鐘不要,很簡單就完成了
不錯,a1 = a2 看上去是比 memcpy(&a1, &a2, 10000) 更簡單,但是別忘了 struct 需要聲明,先不必提動態(tài)文件緩沖區(qū),來看看不同的文件復(fù)制:
memcpy(&p1, &p2, 10001);
memcpy(&p3, &p4, 10002);

劉工你打算聲明多少個結(jié)構(gòu)?

網(wǎng)友評論:向24樓的母親致意!cao 劉前輩(冷漠)的全家!

既然劉前輩(冷漠)如此的不要臉,那么我也不會劉前輩(冷漠)講什么風(fēng)度。我會讓我的小弟們專程上來問候劉前輩(冷漠)的母親。

網(wǎng)友評論:自己不會,就去百度
1、星形網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu): 以一臺中心處理機(jī)(通信設(shè)備)為主而構(gòu)成的網(wǎng)絡(luò),其它入網(wǎng)機(jī)器僅與該中心處理機(jī)之間有直接的物理鏈路,中心處理機(jī)采用分時或輪詢的方法為入網(wǎng)機(jī)器服務(wù),所有的數(shù)據(jù)必須經(jīng)過中心處理機(jī)。 星形網(wǎng)的特點(diǎn): (1)網(wǎng)絡(luò)結(jié)構(gòu)簡單,便于管理(集中式); (2)每臺入網(wǎng)機(jī)均需物理線路與處理機(jī)互連,線路利用率低; (3)處理機(jī)負(fù)載重(需處理所有的服務(wù)),因?yàn)槿魏蝺膳_入網(wǎng)機(jī)之間交換信息,都必須通過中心處理機(jī); (4)入網(wǎng)主機(jī)故障不影響整個網(wǎng)絡(luò)的正常工作,中心處理機(jī)的故障將導(dǎo)致網(wǎng)絡(luò)的癱瘓。 適用場合:局域網(wǎng)、廣域網(wǎng)。
2、總線形網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu): 所有入網(wǎng)設(shè)備共用一條物理傳輸線路,所有的數(shù)據(jù)發(fā)往同一條線路,并能夠由附接在線路上的所有設(shè)備感知。入網(wǎng)設(shè)備通過專用的分接頭接入線路?偩網(wǎng)拓?fù)涫蔷钟蚓W(wǎng)的一種組成形式。 總線網(wǎng)的特點(diǎn): (1)多臺機(jī)器共用一條傳輸信道,信道利用率較高; (2)同一時刻只能由兩臺計算機(jī)通信; (3)某個結(jié)點(diǎn)的故障不影響網(wǎng)絡(luò)的工作; (4)網(wǎng)絡(luò)的延伸距離有限,結(jié)點(diǎn)數(shù)有限。 適用場合:局域網(wǎng),對實(shí)時性要求不高的環(huán)境。
3、環(huán)形網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu): 入網(wǎng)設(shè)備通過轉(zhuǎn)發(fā)器接入網(wǎng)絡(luò),每個轉(zhuǎn)發(fā)器僅與兩個相鄰的轉(zhuǎn)發(fā)器有直接的物理線路。環(huán)形網(wǎng)的數(shù)據(jù)傳輸具有單向性,一個轉(zhuǎn)發(fā)器發(fā)出的數(shù)據(jù)只能被另一個轉(zhuǎn)發(fā)器接收并轉(zhuǎn)發(fā)。所有的轉(zhuǎn)發(fā)器及其物理線路構(gòu)成了一個環(huán)狀的網(wǎng)絡(luò)系統(tǒng)。 環(huán)形網(wǎng)特點(diǎn): (1)實(shí)時性較好(信息在網(wǎng)中傳輸?shù)淖畲髸r間固定); (2)每個結(jié)點(diǎn)只與相鄰兩個結(jié)點(diǎn)有物理鏈路; (3)傳輸控制機(jī)制比較簡單; (4)某個結(jié)點(diǎn)的故障將導(dǎo)致物理癱瘓; (5)單個環(huán)網(wǎng)的結(jié)點(diǎn)數(shù)有限。 適用場合:局域網(wǎng),實(shí)時性要求較高的環(huán)境。
4、網(wǎng)狀網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu): 利用專門負(fù)責(zé)數(shù)據(jù)通信和傳輸?shù)慕Y(jié)點(diǎn)機(jī)構(gòu)成的網(wǎng)狀網(wǎng)絡(luò),入網(wǎng)設(shè)備直接接入結(jié)點(diǎn)機(jī)進(jìn)行通信。網(wǎng)狀網(wǎng)絡(luò)通常利用冗余的設(shè)備和線路來提高網(wǎng)絡(luò)的可靠性,因此,結(jié)點(diǎn)機(jī)可以根據(jù)當(dāng)前的網(wǎng)絡(luò)信息流量有選擇地將數(shù)據(jù)發(fā)往不同的線路。 適用場合: 主要用于地域范圍大、入網(wǎng)主機(jī)多(機(jī)型多)的環(huán)境,常用于構(gòu)造廣域網(wǎng)絡(luò)。

http://zhidao.baidu.com/question/80089729.html




網(wǎng)友評論:這兩人前世骨頭混一塊了,唉

網(wǎng)友評論:這是咋回事呢?

網(wǎng)友評論:這個劉前輩就是以前的wxj1952和冷漠。

本來是一個純技術(shù)貼,又被劉前輩wxj1952冷漠給攪了,雖然我已經(jīng)很克制了。查看 劉前輩wxj1952冷漠 的歷史,它們基本上最后都是用上各種下流的手段。不知道所長是不是挖了劉前輩wxj1952冷漠祖墳,以至于對所長這么大的仇恨。

看過所長的帖子,所長雖然孤傲,但是人品技術(shù)絕佳,這點(diǎn)相信大家有目共睹。我維護(hù)所長,并非我認(rèn)識所長,只是敬佩而已,正如我曾維護(hù) hotpower 一樣。我不怕跌份,不會像所長那樣放不下君子身價與小人纏斗,只能退走,任由小人肆意中傷。

所長的離去,真是可惜,還有 iceage, 算法方面比highgear 還高,c++ 更是令 highgear望塵莫及,可惜他們都太君子了。

網(wǎng)友評論:

誰說keil C51結(jié)構(gòu)拷貝不能優(yōu)化?!LZ自己不會優(yōu)化,就以為所有的人都不會比自己更高明?真以為自己天下第一呢。

呵呵,讓小輩我來教教你,LZ 睜大眼睛看清楚,俺是怎么實(shí)現(xiàn)優(yōu)化的。把LZ的memcpy( )從282字節(jié)優(yōu)化到了22字節(jié)。




一下子顯得LZ這種探討沒了一點(diǎn)意義,純粹是自己無知,什么“一字節(jié)復(fù)制使用了大量代碼,效率極其低下!边玩到了C++來解決keil C51效率低下的問題?
本想貶低他人,結(jié)果還是讓keil 羞辱了一把。你當(dāng)keil 這個老外德國人像你這么蠢?
1#
可以看到,僅僅一個字節(jié)的復(fù)制,竟然使用了大量的代碼,效率及其低下.
這就是說,Keil C 中”結(jié)構(gòu)直接復(fù)制” 簡單的調(diào)用了 memcpy。
真像那么回事似地。我KEIL C調(diào)用了所長的memcpy( ) ? 誰調(diào)用誰呀,裝腔作勢似地。 你的memcpy( ) 能像結(jié)構(gòu)復(fù)制這樣優(yōu)化? 你玩一個給俺瞧瞧,開開眼。別光顧著指責(zé)別人這不行,那不對;很簡單的道理,你玩一個對的、漂亮的給我們菜鳥看看,做個模板讓我們學(xué)習(xí)。別光憑嘴巴說,玩文化產(chǎn)業(yè),忽悠我們菜鳥不懂 ?

唬得了一時騙不了長久 。騙到54 歲了還大忽悠呢。
13樓早就告訴你,結(jié)構(gòu)拷貝可以寄存器優(yōu)化,而memcpy()無法實(shí)現(xiàn)(用戶實(shí)參指針,你能優(yōu)化?好好動動腦子)。竟然沒聽懂別人說的是什么。

呵呵,所長“天下第一高手”這幾天又要在家研究memcpy 的優(yōu)化問題了。一定要和別人比較個高下?
累不累?


、、

、、

網(wǎng)友評論:別,這個是地址復(fù)制吧。

網(wǎng)友評論:小朋友真會開玩笑,拿魔術(shù)這一套來糊弄人



說白了就是自己寫個類似頭文件的東東拿來騙人的

網(wǎng)友評論:我承認(rèn)我比較菜,我把Keil能更改的設(shè)置全改一遍,仍然得不到劉xx圖示的結(jié)果,說人家PS的吧,無憑無據(jù)不能亂說。仔細(xì)看圖片代碼才發(fā)現(xiàn)問題的癥結(jié)所在
我們編譯器自帶的C?COPY是插在Main函數(shù)之前的,而且不會有LOOP1這種指定地址的方式的,他的C?COPY函數(shù)為什么會在Main函數(shù)之后,
再看那個項(xiàng)目怎么比我們自己做實(shí)驗(yàn)多了個文件夾,結(jié)果就是那樣簡單,就像把劉謙的魔術(shù)放慢了仔細(xì)看,就知道他是怎么變出花樣來了。
這種把戲拿來娛樂一下大家,炫耀一下自己是不錯的
但拿來PK那就有點(diǎn)勝之不武了,不過對小孩子嘛,用不著上火動氣,自會有家長管教的

網(wǎng)友評論:

代碼開銷:和復(fù)制1字節(jié)一樣。282字節(jié)。當(dāng)然時間可能不一樣,C51拷貝什么都是逐字節(jié)來的。反正C51上感覺不到,和復(fù)制1字節(jié)一樣快
-------------------------------
使用時鐘周期/字節(jié).你就知道是不是一樣快了.
就是在c51上,優(yōu)化還是有可能的.
-----------------------------------------------
不信你做一個32k字節(jié)的復(fù)制試試.
最快速的代碼是最長的代碼,最小的代碼是最慢的代碼
在高性能計算理論里,這叫做循環(huán)展開
------------------------------------------------
只會用for和while,卻不會選移動操作的人,還是一邊休息吧.
DMA快,但是是硬件層,這里不談

網(wǎng)友評論:

34樓aihe,我來教你怎么優(yōu)化。你得不到結(jié)果,不一定是別人唬你。如若誰都能做到,LZ就不會在這做這種探討了。
首先282字節(jié)完全是由于?C?COPY這個通用的完整的庫函數(shù)代碼太長的緣故。它是通用的,無論是data——>XDATA,還是idata,xdata之間,都可以互相拷貝,沒什么不好。編譯器首先設(shè)好a1,a2,2個指針,和復(fù)制長度;然后調(diào)用?C?COPY函數(shù)。我想你當(dāng)然知道,所長所說的“效率低下的大量代碼”是干什么用的:

1、a2 指針,在R1(指針低8),R2(指針高8),R3(存貯區(qū)編碼);
2、a1 指針,在R0,R4,R5;(對應(yīng)上述 L,H, 編碼);
3、復(fù)制長度:int 在R6,R7。

效率低下?為了調(diào)用 ?C?COPY,8個寄存器一個也不能優(yōu)化掉。因?yàn)?C?COPY是庫函數(shù)。它要求輸入3個實(shí)參。
所以,要縮寫代碼,只能重寫庫函數(shù)?C?COPY。
既然我是固定存貯區(qū)idata之間復(fù)制10字節(jié),我只要把idata 之間互相復(fù)制的代碼加以利用就行了。其他的編譯器都做了。
我重寫了?C?COPY ,誰不知道項(xiàng)目庫函數(shù)連接順序可以自己設(shè)定?——把自己寫的?C?COPY函數(shù)放在當(dāng)前項(xiàng)目文件目錄里就行了。
還用我把我寫的?C?COPY 函數(shù)源代碼給你看嗎?

冤枉了別人,是不是應(yīng)該有所表示?

很多時候,不是我們比別人高明,只是我們想不到或者沒想到而已;別人一個套想了半年,我們可能想一輩子也想不到;所以,互相學(xué)習(xí)才好。
后面的結(jié)構(gòu)復(fù)制 優(yōu)化到22字節(jié),更難想到了。所長弄出個什么一字節(jié)的結(jié)構(gòu)復(fù)制!然后由此下結(jié)論:KeilC 不行,沒他的C++好。下這種套?還C++ 解決?結(jié)果把自己繞進(jìn)去了。

、、、、

網(wǎng)友評論:

我沒冤枉你吧,是你重寫了?C?COPY函數(shù),不是德國佬怎么高明,其他編譯器也可以這樣做的,也不是你特別能耐,也不能證明Keil在這點(diǎn)上比其他編譯器優(yōu)越啊,
O(∩_∩)O哈哈~

網(wǎng)友評論:做硬件的不知道你們所云,呵呵淡定的飄過~

網(wǎng)友評論:

呵呵,aihe如若會重寫庫函數(shù),早就想到了。那么也就不會有34樓的魔術(shù)疑問了。

還有,像那種“多了一個文件夾test”的問題,我看別人下面都是好幾個文件夾,——那些都是文本文件或者是其它項(xiàng)目文件,可以隨時換項(xiàng)目或者添加C文件的。


至于Keil C51 系統(tǒng)自帶的?C?COPY 和memcpy( )比較的問題,所長已經(jīng)一開始就證明了,2者代碼完全一致,2者效率完全一樣,都同樣低下。自己把自己的memcpy( )否定了。面對事實(shí),不得不。


aihe 還真有點(diǎn)特殊,你把memcpy( )實(shí)驗(yàn)也用同一個編譯器做一下看,結(jié)果完全一樣。8個寄存器設(shè)置,然后調(diào)用?C?COPY庫函數(shù)。

如若懶得做,(怎么證明別人錯的時候那么大精神,各種設(shè)置值都實(shí)驗(yàn)了一遍。)輪到證實(shí)自己錯誤的時候就懶得做了?咱們都是上海人,老鄉(xiāng),不會互相開打吧。
我?guī)湍阕鲆槐椋?br>
、、

網(wǎng)友評論:我呢是比較菜,但是我相信Keil自帶的函數(shù)肯定是有他的道理,他們也不是白癡
開始我寫函數(shù)的時候,看別人的函數(shù)都是太復(fù)雜了,偷偷得精簡
不過到后來,考慮移植和通用,慢慢的寫的和人家的就差不多了
說錯話,做錯事不要緊,別人指正時只要虛心接受,有則改之無則加勉就可以了
我才沒事找人開打,不過那兒人都一樣,只要保持住自己的心境,淡定淡定,O(∩_∩)O哈哈~

網(wǎng)友評論:這下可以看清第二個文件夾 test 里的內(nèi)容了。上面的內(nèi)容主要是自己的隱私文件名,不愿公開而已。



網(wǎng)友評論:

既然你這么愿意幫忙,那就幫我把前幾個月寫的一段程序再優(yōu)化優(yōu)化,注芯片是STM8

void EE_Wrait(unsigned int pSrc, unsigned int pDst,unsigned char ucLength) //寫數(shù)據(jù)內(nèi)置存儲器
{ //從源地址寫入到----目的地址----長度
unsigned char ucCount;
unsigned char *pDstAddr = (unsigned char *)pDst;
unsigned char *pSrcAddr = (unsigned char *)pSrc;
// 對數(shù)據(jù)EEPROM進(jìn)行解鎖
do
{
FLASH_DUKR = 0xae; // 寫入第二個密鑰
FLASH_DUKR = 0x56; // 寫入第一個密鑰
}
while((FLASH_IAPSR & 0x08) == 0); // 若解鎖未成功,則重新再來

for(ucCount=0;ucCount<ucLength;ucCount++)
{
*pDstAddr = *pSrcAddr;
while((FLASH_IAPSR & 0x04) == 0); // 等待寫操作成功
pSrcAddr ++;
pDstAddr ++;
}
}

網(wǎng)友評論:劉工,這就對了,你若技術(shù)討論,那么就繼續(xù)技術(shù)討論;若繼續(xù)污言穢語惡意中傷,那highgear就奉陪,繼續(xù)問候你的家人。

劉工,優(yōu)化 C?COPY 沒有意義,無論再如何優(yōu)化,keil c 下 a1 = a2 的效率都是很低。一個簡單的一字節(jié)結(jié)構(gòu),仍然使用大量代碼,優(yōu)化 c?copy 失去了意義。而且,我一直強(qiáng)調(diào), keil c 沒有DMA 或 block Move 指令,因此,memcpy 的效率也不會比手工 c 代碼高。

不必糾纏在 C?COPY 的優(yōu)化上,此舉對 a1 = a2 幫助不大。

網(wǎng)友評論:a1 = a2 在 keil c 下效率低下,而 Visual C++ 生成的代碼卻效率極高.

一字節(jié)結(jié)構(gòu):
a1 = a2;
004113B2mov al,byte ptr [a2]
004113B5mov byte ptr [a1],al

3 字節(jié)結(jié)構(gòu):

a1 = a2;
004113B2mov ax,word ptr [a2]
004113B6mov word ptr [a1],ax
004113BAmov cl,byte ptr [ebp-12h]
004113BDmov byte ptr [ebp-6],cl

8 字節(jié)結(jié)構(gòu):
a1 = a2;
004113BCmov eax,dword ptr [ebp-20h]
004113BFmov dword ptr [ebp-10h],eax
004113C2mov ecx,dword ptr [ebp-1Ch]
004113C5mov dword ptr [ebp-0Ch],ecx

12 字節(jié)結(jié)構(gòu):
a1 = a2;
004113BCmov eax,dword ptr [ebp-28h]
004113BFmov dword ptr [ebp-14h],eax
004113C2mov ecx,dword ptr [ebp-24h]
004113C5mov dword ptr [ebp-10h],ecx
004113C8mov edx,dword ptr [ebp-20h]
004113CBmov dword ptr [ebp-0Ch],edx

直至25字節(jié)以上,vc++ 才開始使用block move, 并未像 keil c 那樣調(diào)用 memcpy.
a1 = a2;
0041354Cmov ecx,6
00413551lea esi,[ebp-48h]
00413554lea edi,[ebp-24h]
00413557rep movs dword ptr es:[edi],dword ptr [esi]
00413559movs byte ptr es:[edi],byte ptr [esi]

通過比較,可以這么猜測:結(jié)構(gòu)復(fù)制在 c 不常用的原因,導(dǎo)致 keil c 并未對其優(yōu)化;而 vc++ 中則因?yàn)榻Y(jié)構(gòu)復(fù)制的大量使用(c++中,結(jié)構(gòu)是all public 的類),則特別優(yōu)化,手工生成的代碼也不過如此了。

網(wǎng)友評論:

如果對 c?copy 優(yōu)化感興趣,可以看看 keil c 論壇的帖子(我前面摘抄的英文源自于此):

http://www.keil.com/forum/6950/
http://www.keil.com/forum/8701/

Custom ?C?COPY ?
Bill Webster
I would dearly love to replace some of the Keil library functions that are used by intrinsics, such as ?C?COPY, which is called by memcpy (and by other things). My current goal is to generate runtime errors on certain types of copies, but replacement would be useful for other purposes.

I've actually written my own implementation of ?C?COPY, which works fine. The inline instructions are still emitted by the compiler and my version is linked.

However, I'm concerned about compatibility with future compiler releases.

I'm supposing that the interface can't change, because this would break older libraries, which could be third party.

But other library functionality may depend on something internal to the Keil ?C?COPY implementation, or may do so in future.

For my current purposes, I'm thinking of patching the entry to the Keil ?C?COPY after the code is built, to call my checking routine. This only requires that the interface doesn't change.

Has anyone else tried anything like this? Any comments on my assumption that the interface can't change?

PS - I know I can acheive my ends by writing my own memcpy and redefining memcpy() with a macro, but then heaps more code will be generated, because the calls will be far less efficient, without the special parameter passing.

網(wǎng)友評論:43樓aihe 的幫忙工作有沒有效益?若是一般研究,我就交給學(xué)生做了。
小意思,可以到我家里來共同探討。我請你吃飯。
我住靜安。

網(wǎng)友評論:我等,程序盲,基本不會考慮效率問題,最直接的方法是升級處理器~~

網(wǎng)友評論:

2個相同算法之間相差幾十個字節(jié)長度,根本無所謂效率問題,又不是核反應(yīng)堆。
而且多數(shù)情況下,code 長度大(實(shí)際開銷。┑哪莻算法更通用完善。

像LZ 指責(zé)keil C51 代碼效率低,又臭又長,純粹是無知。微軟的Windows 臭不臭,長不長?LZ 優(yōu)化一個給蓋茨 看看?到微軟應(yīng)聘去吧。在這混,太屈才了。



、、

網(wǎng)友評論:

43樓 aihe:

學(xué)生交卷了,換了一種算法,code 縮減了一半多!δ芡耆粯。
請你檢驗(yàn)一下,有什么錯誤沒有。如果正確,是不是應(yīng)該表示一下?錯了請指正。(我說他寫的不錯,如果證實(shí),還得再次點(diǎn)名欣賞,可以就此強(qiáng)調(diào)一下概念。)

無論正/ 誤,都可以讓網(wǎng)友學(xué)習(xí)一下。

修改代碼如下:
void EE_Wrait(unsigned intpSrc,unsigned intpDst,unsigned charucLength)
{
unsigned char ucCount;
unsigned charidata * pDstAddr =&pDst;
unsigned charidata * pSrcAddr =&pSrc;

do
{
FLASH_DUKR = 0xae;
FLASH_DUKR = 0x56;
}

while((FLASH_IAPSR & 0x08) == 0);

for(ucCount=0; ucCount < ucLength; ucCount++)
{
pDstAddr [ucCount] = pSrcAddr [ucCount] ;

while((FLASH_IAPSR & 0x04) == 0);
//pSrcAddr ++;
//pDstAddr ++;
}
}
code= 52 ; // 還要優(yōu)化么?

原code=139 ;


//

網(wǎng)友評論:43樓 aihe老師的程序已是最優(yōu)化的了,贊一個~~~

aihe老師注明芯片是STM8,真搞不懂,LS的大師怎么把51的 idata 存儲器用于STM8? STM8芯片有 idata 存儲器嗎?

網(wǎng)友評論:學(xué)習(xí)了

網(wǎng)友評論:
43樓 aihe:

學(xué)生交卷了,換了一種算法,code 縮減了一半多!δ芡耆粯。
請你檢驗(yàn)一下,有什么錯誤沒有。如果正確,是不是應(yīng)該表示一下?錯了請指正。(我說他寫的不錯,如果證實(shí),還得再次點(diǎn)名欣賞,可以就 ...
劉前輩 發(fā)表于 2011-5-13 11:32
void EE_Wrait(unsigned intpSrc,unsigned intpDst,unsigned charucLength)
{
unsigned char ucCount;
unsigned charidata * pDstAddr =&pDst;
unsigned charidata * pSrcAddr =&pSrc;


pDstAddr =&pDst根本就是錯誤的,怎么改的?

網(wǎng)友評論:LS小六子,大師哪會錯?

錯的肯定不是小三就是小六~~~

網(wǎng)友評論:把你的程序替代,編譯通不過

#error cpstm8 main.c:43(31+4) incompatible pointer types

我是這樣調(diào)用的
EE_Wrait((unsigned int)&Sys_Set[0].Tim2_F,(0x4000+(((unsigned int)&Sys_Set[0].Tim2_F)-(unsigned int)&Sys_Set[0])),sizeof(Sys_Set[0].Tim2_F));
或這樣
EE_Wrait((unsigned int)&Start_Set,0x4000,sizeof(Start_Set));

但是我發(fā)現(xiàn)我的代碼并不是很優(yōu)化,比另外的寫法多占有空間,但是這樣寫很直觀

網(wǎng)友評論:
    IAR STM8 1.2 直接使用__eeprom關(guān)鍵字訪問EEPROM

    STM8L15X:
    #include "stm8l15x_conf.h"

    void __eeprom_write_8(unsigned short addr_eep,unsigned char data)
    {
    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    FLASH_Unlock(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep, data);

    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    FLASH_Lock(FLASH_MemType_Data);
    }

    void __eeprom_write_16(unsigned short addr_eep,unsigned short data)
    {
    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    FLASH_Unlock(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep, data/256);
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep+1, data%256);
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_Lock(FLASH_MemType_Data);
    }

    void __eeprom_write_32(unsigned short addr_eep,unsigned long data)
    {
    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    FLASH_Unlock(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep, (unsigned char)(data>>24));
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep+1, (unsigned char)(data>>16));
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep+2, (unsigned char)(data>>8));
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_ProgramByte(addr_eep+3, (unsigned char)(data>>0));
    FLASH_WaitForLastOperation(FLASH_MemType_Data);

    FLASH_Lock(FLASH_MemType_Data);
    }


    void __eeprom_write_many(unsigned short addr_eep,unsigned short size,unsigned short dummy,unsigned short addr_ram)
    {

    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    FLASH_Unlock(FLASH_MemType_Data);

    for(unsigned short i=0;i<size;i++)
    {
    FLASH_ProgramByte(addr_eep+i, *((unsigned char *)(addr_ram)+i));
    FLASH_WaitForLastOperation(FLASH_MemType_Data);
    }


    FLASH_Lock(FLASH_MemType_Data);

    }



    STM8S:
    #include "stm8s_conf.h"

    void __eeprom_write_8(unsigned short addr_eep,unsigned char data)
    {
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    FLASH_Unlock(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep, data);

    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    FLASH_Lock(FLASH_MEMTYPE_DATA);
    }

    void __eeprom_write_16(unsigned short addr_eep,unsigned short data)
    {
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    FLASH_Unlock(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep, data/256);
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep+1, data%256);
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_Lock(FLASH_MEMTYPE_DATA);
    }

    void __eeprom_write_32(unsigned short addr_eep,unsigned long data)
    {
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    FLASH_Unlock(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep, (unsigned char)(data>>24));
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep+1, (unsigned char)(data>>16));
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep+2, (unsigned char)(data>>8));
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_ProgramByte(addr_eep+3, (unsigned char)(data>>0));
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);

    FLASH_Lock(FLASH_MEMTYPE_DATA);
    }


    void __eeprom_write_many(unsigned short addr_eep,unsigned short size,unsigned short dummy,unsigned short addr_ram)
    {

    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    FLASH_Unlock(FLASH_MEMTYPE_DATA);

    for(unsigned short i=0;i<size;i++)
    {
    FLASH_ProgramByte(addr_eep+i, *((unsigned char *)(addr_ram)+i));
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_DATA);
    }

    FLASH_Lock(FLASH_MEMTYPE_DATA);
    }


    主程序測試:
    volatile __eeprom __no_init char eep_u8;
    volatile __eeprom __no_init short eep_u16;
    volatile __eeprom __no_init long eep_u32;

    void main( void )
    {
    eep_u8=123;
    eep_u16=12345;
    eep_u32=123456789;

    while(1);

    }
復(fù)制代碼

網(wǎng)友評論:

123jj先別太興奮,不加idata一樣。關(guān)鍵是躲過調(diào)用庫函數(shù)。學(xué)生不過是移植到C51寫的程序,連我也沒玩過STM8。

小心最后自己打了自己的臉,讓年輕學(xué)生弄個瞠目結(jié)舌不好看。尤其是女性。又是比他們年長20歲的女性。一個異型 MCU 你贏了他們二十幾歲的學(xué)生很光彩是吧!澳銈儾欢伞揖汀 呵呵,他們懂的東西,你這輩子入不了門。連皮毛都不可能懂。所長硬撐著都不懂,別說你了。

你還是專心注意力關(guān)心把自己的小車站起來為好。別老把眼睛盯著別人,跟所長似的,什么事非要和別人比個高下才興奮?越比對手年齡越小了,現(xiàn)在和23歲的在校生對陣了?

學(xué)生說他再去看看STM8手冊,我說不用,我一樣給你優(yōu)秀!研究生C語言你免考了。(你用不著把所有的MCU都去學(xué)會,你將來不是要打工的。你是做研究的,你以后的道路和別人不一樣。)

有些人,干了一輩子,都在為別人打工。她什么類型的MCU都會一點(diǎn),市場刷新太快,結(jié)果一生疲于奔命。其實(shí)我看這些自以為是的中年工程師,一輩子連51都學(xué)不好。會STM8?有用么?月薪最多10T而已。二踢腳,一生就這么過去了。姐姐還有發(fā)展前途?
學(xué)生23歲,我看他比你43歲寫的程序強(qiáng)多了。

再告訴你和你尊重的所長,為什么51你們學(xué)一輩子也學(xué)不到頭,看下面附件,……什么都知道點(diǎn)皮毛,然后就以為都會了。以為keil C效率低下?德國佬不過如此,缺少見識,看看德國佬干了什么,你技術(shù)生命不可能再學(xué)新技術(shù)了吧,現(xiàn)在知道再開始學(xué)也晚了……,這一生大概也只能玩玩小車了。

我還欠你10分,給不出去。

論壇上我就尊重2個人:殷文躍,XXX_xxx,他們看的懂我貼的是什么。他們知道KeilC51的分量,從來不在這方面輕浮裝懂。知道自己一生該干什么。



、、

網(wǎng)友評論:談不上興奮不興奮,反正俺C語言不懂,那幾十條基本指令都寫不全。

無知者無畏,俺早就不搞技術(shù)啦,怎么寫程序?那是N年前的歷史啦,已基本上忘個精光~~~

關(guān)于小車,前后匠人、老T叔撐著,后有 不光寫程序小盆友跟著,哪里輪得上俺這個半吊子出手?

不過有一點(diǎn)劉小輩說對啦,俺的一生疲于奔命,養(yǎng)家糊口,買房養(yǎng)LP,還要供孩子留學(xué)。

一生就這么過去了。沒有發(fā)展前途,彼此彼此,劉小輩也差不多如此吧,有能耐的人從不會把精力花在二姨家灌水。!

至于這一生也只能玩玩小車?這一點(diǎn)劉小輩也說對啦,俺小車也玩不轉(zhuǎn),要依靠匠人、老T叔、highgear、不光寫程序等等,這些網(wǎng)友大力支持,沒有這些網(wǎng)友的大力支持,俺一天也玩不下去。。。。。。。因?yàn)閷@小玩意兒提不起興趣。

聽說劉小輩幾年前就玩小車?何不拿出來曬一曬,讓俺們菜鳥開開眼見~~~

網(wǎng)友評論:

避開51data寫一個。學(xué)生的長輩是中醫(yī)專家,總是教育后輩,中醫(yī)界尤其反感什么事還沒做到的時候就吹,“包治百病”“手到病除”“攻克癌癥”……(“移植”到論壇就是別人寫程序還在調(diào)試階段,就以為是最終結(jié)果了;就開始貶低他人不懂。認(rèn)為別人很差勁……這也太著急了吧,高興的太早了吧!┲嗅t(yī)界總是“我不能保證……容我試試……”。什么事給自己留后路。免得最后下不來臺!矊懡o所長,別堅持了幾年 memcpy( ) ,實(shí)在下不來臺,又換C++ 了。C++最后也不行,他還有C# ,還有JAVA。別到后來說胡話了。

#include<absacc.h>


void EE_Wrait(unsignedint pSrc, unsignedint pDst,unsigned char ucLength)
{
do
{
FLASH_DUKR = 0xae;
FLASH_DUKR = 0x56;
}
while((FLASH_IAPSR & 0x08) == 0);

while(ucLength--)
{
DBYTE[pSrc] = DBYTE[pDst];
while((FLASH_IAPSR & 0x04) == 0);
pSrc++;
pDst++;
}
}
一樣,code=51字節(jié).

什么?STM8 沒有absacc.h ?! ——學(xué)生自己做的。


、、

網(wǎng)友評論:淡定,淡定
技術(shù)以外的東西大家去同僚老鄉(xiāng)版面去侃
劉xx的程序我放到Keil中試過了,優(yōu)化效果的確明顯
我先說我程序的缺點(diǎn):
1、把++,改為——,改判零,會再少一個字節(jié)
2、開鎖用完后沒把鎖再鎖上,易招賊,(誤寫入)
劉xx你程序的問題在于:看我的函數(shù)名和注釋就知道這是一個用于寫EEROM的程序,無論哪個單片機(jī)EEROM都不能用IDATA存取,不符合題意。

網(wǎng)友評論:

感謝老鄉(xiāng),59樓的程序改過了,可行?

把下面的DATA存儲區(qū)說明修改成EEROM 區(qū)就行了。
DBYTE[pSrc] = DBYTE[pDst];

要不我拿個STC的EEROM 程序幫你改?反正都是學(xué)生作業(yè),學(xué)生做完了還可以寫論文;這種實(shí)戰(zhàn)程序,評委都不懂的,只好給論文優(yōu)秀。

有點(diǎn)錯更好啊,BUG越多越好,查錯才增長能力呢。一帆風(fēng)順學(xué)生論文還沒內(nèi)容可寫。


//

網(wǎng)友評論:



實(shí)際效果出來了,你那個程序比我那個多用了20個CODE
因?yàn)槲胰サ袅薸data

在Keil下面如果去掉idata也會這樣效果。。。
你自己試一下就知道了
我再重申一下,這個是寫EEPROM的程序,沒辦法給你評優(yōu)
你再想一下,如果數(shù)據(jù)長度是200,你你那個程序能正常運(yùn)行嗎?

網(wǎng)友評論:俺在51樓已說過了,aihe老師的程序已是最優(yōu)化的了,有截圖為證。

可惜,aihe老師不相信俺~~~
43樓 aihe老師的程序已是最優(yōu)化的了,贊一個~~~

......

123jj 發(fā)表于 2011-5-13 12:11


網(wǎng)友評論:

62樓 aihe 朋友:沒關(guān)系,小事一樁,很多方法,變通;
我原來不懂STM8,還不如我學(xué)生呢。學(xué)生說他查了一晚上資料就入門了。

1、你把下面的指針定義前面加上 @near ,也就是:

@near unsigned char *pDstAddr = (unsigned char *)pDst;
@near unsigned char *pSrcAddr = (unsigned char *)pSrc;

其它(你的程序)都不變,試試看什么效果;如果有效,一定告知。我好通知學(xué)生!覍(shí)在不愿安裝什么STM8開發(fā)環(huán)境。只能看看書了。這是把3字節(jié)指針化為2字節(jié),編譯結(jié)果按照C編譯器規(guī)則,肯定簡化!@與Keil C51 使用idata 原理一樣。

還有,書上都有的程序,我覺得還是參考書上的好;書上的標(biāo)準(zhǔn)程序是廠家提供的,時序上肯定測試多少遍了。咱們用戶只管調(diào)用,恐怕不能隨便化簡吧。即使自己的程序好不容易通過,心里也沒底。誰知道芯片時序是什么樣?——換個環(huán)境程序又不靈了,怎么辦?

下面是書上的程序,要寫200個字節(jié)更簡單了;利用成塊寫入功能,按照128字節(jié)一個單位塊來寫,——又快又簡單。廠家提供的現(xiàn)成程序,一天就完成了。
不用自己下那么大工夫研究。

下面是廠家提供的按字節(jié)寫EEROM操作標(biāo)準(zhǔn)程序。



需要成塊編寫程序請告知。有必要把電子書發(fā)給你。(我今天看了一上午就大概明白了。)
我覺得你應(yīng)該也有。而且肯定參考過比我更詳細(xì)的資料!幻靼诪槭裁匆约簩。我絕對寫不過廠家——除非我在廠家做測試。
不過添加 @near 是我自己認(rèn)為的,keilC實(shí)驗(yàn)出來的。

廠家程序?qū)懙恼媸菬o可挑剔,沒有3字節(jié)指令定義的情況!獩]地方需要加@near 。




、、

網(wǎng)友評論:真是的還不清楚嗎?
@near和XDATA一樣的意思
idata只能用在RAM的最前256字節(jié),超過這個數(shù)字出現(xiàn)的結(jié)果無法預(yù)料?!
再說一下,哪個MCU的EEROM在idata的取址范圍里?!

網(wǎng)友評論:

aihe你說得對,我的@near是加在你自己定義的指針pDstAddr前面的 ,僅僅是說明你這個指針是個指向xdata區(qū)域 數(shù)據(jù)的指針,它只需要2字節(jié)分配(如果不加,那編譯器默認(rèn)指針3字節(jié)指針。)STM8編譯器把它分配在哪,是編譯器的事,與用戶無關(guān),這2個指針指向EEROM地址 pDst ,或 pSrc。 和EEROM 讀寫的數(shù)值沒關(guān)系,它只是個地址值,例如4000H。——它指向4000H,* pDstAddr 從4000H取數(shù)值,和pDstAddr 分配放在哪(xdata / idata ) 沒有關(guān)系,這和所有C語言概念一樣。
也許應(yīng)該像下面這樣:

unsigned char * @near pDstAddr = (unsigned char *)pDst ;

如果你希望分配在256字節(jié)RAM區(qū)內(nèi),應(yīng)該用@tiny ,關(guān)鍵是@near 或者 @tiny 的位置。keil C很簡單,如果形如
xdataint* idataptr;

說明ptr指向 xdata 區(qū)的 int ,而ptr在data 區(qū)。顯然數(shù)據(jù)操作在Xdata區(qū)。 STM8我無法實(shí)驗(yàn),看書上意思一樣。

還有,我理解的沒什么偏差,我看過書上的標(biāo)準(zhǔn)程序,沒錯。

你需要發(fā)給你看看,我以為你有。所以沒貼。

@eeprom unsigned char * pDstAddr = (unsigned char *)pDst ;
unsigned char @near * pDstAddr = (unsigned char *)pDst ;

都可能對,但意義不一樣。

等一等,我明白了。主要EEROM是什么區(qū)的問題?好像書上講明了。
還有一點(diǎn)。請問aihe ,你的2個指針都指向EEROM? 那你的程序好像沒通過?A,B倆個指針都指向EEROM,*A=*B;能行?可能還是要通過中間緩存。我認(rèn)為至少pSrc不能是EEROM區(qū)。

@eeprom unsigned char* pDstAddr = (unsigned char *)pDst;
@near unsigned char *pSrcAddr = (unsigned char *)pSrc;

第二個@near 在64Kflash下是默認(rèn)的,不用寫也行。









、、

網(wǎng)友評論:*A=*B能行,但A[n]=B[n]就不一定行

你改的快,我在朋友家?guī)兔π迻|西,順便腐敗一下,沒時間,截圖都準(zhǔn)備好了,只是沒貼出來
你再看看我第二次說的,怎么調(diào)用這個程序,你就明白,我有可能從RAM寫到EEROM,也有可能從FLASH寫到EEROM,有可能是整個結(jié)構(gòu)體寫入,例如首次開機(jī)初始化,有可能只寫1、2個字節(jié)用來修改部分參數(shù)還有可能接受外部的一次性修改,但是我并不需要從EEROM到EEROM,這個沒必要

網(wǎng)友評論:

明白了。書上3種方式都有范例。明天貼給你,我覺得加入下面語句很重要。你沒加是有原因?
/* 設(shè)置編程時間,F(xiàn)IX =1:編程時間固定為標(biāo)準(zhǔn)編程時間tprog。*/
FLASH_CR1 &= (unsigned char)(~0x01);
FLASH_CR1 |= 0x01;
A[n]=B[n]; 是要修改前面形參才可以的。例如:DBYTE 初始指向4000H而不是0000H。

2個指針不是同時指向EEROM就好辦了。按書上來,和你寫的也差不多,書上是按照存儲區(qū)不同來區(qū)分EEROM的;例如寫入4000H一字節(jié)就至少要3ms 。優(yōu)化不優(yōu)化關(guān)系不大。能縮減50個字節(jié),效率一樣。


、、

網(wǎng)友評論:編程時間在初始化中,不放在這里更好,你說呢?
還有無論@tiny放在哪里編譯都通不過的。

在Keil中用idata只能在局限范圍內(nèi)使用,你試試看吧。

網(wǎng)友評論:

已經(jīng)知道代碼開銷由指針引起,避免很容易:(EEROM段設(shè)置很簡單)

void EE_Wrait(unsigned int pSrc, unsigned int pDst,unsigned char ucLength) //寫數(shù)據(jù)內(nèi)置存儲器
{ //從源地址寫入到----目的地址----長度
unsigned char ucCount;

// 對數(shù)據(jù)EEPROM進(jìn)行解鎖
do
{
FLASH_DUKR = 0xae; // 寫入第二個密鑰
FLASH_DUKR = 0x56; // 寫入第一個密鑰
}
while((FLASH_IAPSR & 0x08) == 0); // 若解鎖未成功,則重新再來

for(ucCount=0;ucCount<ucLength;ucCount++)
{
*(unsigned char *)pDst = *(unsigned char *)pSrc;
while((FLASH_IAPSR & 0x04) == 0); // 等待寫操作成功
pSrc ++;
pDst ++;
}
}

code 縮減1/3 ?——需要修改細(xì)節(jié)?從這里并看不出pDst是EEROM 區(qū)還是flash, Xdata RAM區(qū)。無所謂的,只要是指向004000H的指針就行。這是仿馮諾依曼結(jié)構(gòu),大家共64K/128K地址,讀EEROM區(qū)和讀 SRAM(Xdata)區(qū)一樣指令?知道寫入不一樣就行了。


、、

然后討論如何調(diào)用這個函數(shù)。


、、

網(wǎng)友評論:#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21(5) missing expression
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
#error cpstm8 main.c:21 bad character ?
main.c:
The command: "cxstm8 +mods0 +debug -pxp -no -pp -l -i"c:\program files\cosmic\cxstm8_32k\hstm8" -i"C:\Program Files\COSMIC\CXSTM8_32K\Hstm8"-clDebug\ -coDebug\ main.c" has failed, the returned value is: 1
exit code=1.

test.elf - 11 error(s), 0 warning(s)
編譯還是不過
COSMIC編譯要求很嚴(yán)的

網(wǎng)友評論:

很簡單的調(diào)試:刪去無關(guān)項(xiàng),看看到底哪錯:
void EE_Wrait(unsigned int pSrc, unsigned int pDst,unsigned char ucLength)
//寫數(shù)據(jù)內(nèi)置存儲器
{ //從源地址寫入到----目的地址----長度
unsigned char ucCount;

for(ucCount=0;ucCount<ucLength;ucCount++)
{
*(unsigned char *)pDst = *(unsigned char *)pSrc;
pSrc ++;
pDst ++;
}
}

上面是內(nèi)存拷貝程序,與EEROM無關(guān)。若錯就是上面寫錯了,很好查。

程序基本上是廠商提供的,如若錯,肯定是我們自己哪不對。查吧,懶得查就放棄自己做。采用標(biāo)準(zhǔn)的。


bad character ,是出現(xiàn)了編譯器不接受的字符,——是文字輸入錯誤。很好檢查!皇浅绦蛘Z法錯。

編譯器標(biāo)出哪行錯?告知。還可以學(xué)習(xí)、修改一下:

如若你原來寫的函數(shù)可以用,不如見好就收,你好不容易花時間調(diào)試出來的;我隨便改也不好。改的反而不能用了,不討好的事。
商家都提供了,看不出有什么問題。我不可能比商家寫的更簡單。

在我這怎么優(yōu)化都是很簡單的事,各種簡約方法都很好玩。 要不我裝一個COSMIC C 試試?意義不大。

下面是商家提供的程序:

unsigned int eeprom_address; /* 定義eeprom_address 變量 */

//定義EEPROM字節(jié)寫 函數(shù)
void EEPROM_WRITE_BYTE ( unsigned int eeaddress, unsigned chareedata)
{
eeprom_address = eeaddress;

/* 設(shè)置編程時間,F(xiàn)IX =1:編程時間固定為標(biāo)準(zhǔn)編程時間tprog。*/
FLASH_CR1 &= (unsigned char)(~0x01);
FLASH_CR1 |= 0x01;

/* MASS密鑰,解除EEPROM的保護(hù) */
FLASH_DUKR = 0xAE;
FLASH_DUKR = 0x56;

*((unsigned char*) eeprom_address) = eedata;
//EOP=1,EEPROM編程結(jié)束
while((FLASH_IAPSR & 0x04) != 0x00);
}


看上去明顯避開使用指針,很簡約。


、、


、、

網(wǎng)友評論:*(unsigned char *)pDst = *(unsigned char *)pSrc
這個報錯,呵呵
將地址轉(zhuǎn)換成指針變量時必須強(qiáng)制轉(zhuǎn)換
我覺得從整體考慮,優(yōu)化函數(shù)的輸入?yún)?shù)才是正事
算了也不要你改了,下次哪個網(wǎng)友有更好的方法告訴我一下

網(wǎng)友評論:

有道理。確實(shí)不嚴(yán)格。pSrc/pDst 是常量地址,編譯器嚴(yán)格點(diǎn)就通不過了。

好辦,稍微改改就通過了!仍O(shè)一個uint 變量pSrcAdrr ,不是指針;就行了?磸S商標(biāo)準(zhǔn)程序也是這么干的。


優(yōu)化函數(shù)參數(shù)為指針,確實(shí)方便;不過code 就上去了。所以廠商也沒那么干!降资且玫乃惴,還是要最小的Code 。可能STM8Flash 空間小,所以追求后一項(xiàng)。


、、

網(wǎng)友評論:別費(fèi)那個勁了
就此打住吧

網(wǎng)友評論:void EE_Wrait(unsigned int pSrc, unsigned int pDst,unsigned char ucLength) //寫數(shù)據(jù)內(nèi)置存儲器
{ //從源地址寫入到----目的地址----長度
unsigned char ucCount;
unsigned int pDstAddr = pDst;
unsigned int pSrcAddr = pSrc;
// 對數(shù)據(jù)EEPROM進(jìn)行解鎖
do
{
FLASH_DUKR = 0xae; // 寫入第二個密鑰
FLASH_DUKR = 0x56; // 寫入第一個密鑰
}
while((FLASH_IAPSR & 0x08) == 0); // 若解鎖未成功,則重新再來

for(ucCount=0;ucCount<ucLength;ucCount++)
{
*(unsignedchar *)pDstAddr = *(unsignedchar *)pSrcAddr;
while((FLASH_IAPSR & 0x04) == 0); // 等待寫操作成功
pSrcAddr ++;
pDstAddr ++;
}
}

Keil C 通過?赡 pDstAddr ++; 會因硬件特殊報錯。


//

網(wǎng)友評論:編譯通過,截圖為證,到此為止





網(wǎng)友評論:

我說以下幾點(diǎn),僅供討論:
1. struct在c++中與class一樣,是用來定義類的,它們之間的區(qū)別是: struct默認(rèn)的成員屬性是public的,class默認(rèn)的是private.

2. A a1 = a2調(diào)用的是copy constructor. 而a1 = a2 調(diào)用的是assignment operator 函數(shù)(以下簡稱二個函數(shù))。當(dāng)你定義自己的類時,如果自己定義了這些函數(shù),那我們沒有爭議,當(dāng)然是調(diào)用這些函數(shù)。

3. 當(dāng)我們沒定義這二個函數(shù)時,編譯器并不一定為我們提供這二個函數(shù)。提不提供要看你的類的定義具不具有 bitwise copy的語義。如果具有bitwise copy的語義,則編譯器并不提供這二個函數(shù),而是直接進(jìn)行member-wise r 復(fù)制,而這種復(fù)制各種編譯器的實(shí)現(xiàn)并不相同。如果不具有bitwise copy的語義,則會我們提供默認(rèn)的這兩二個函數(shù)。
4. 類具有以下四種特征時,則不具備bitwise 語義:
a. 當(dāng)這個類有一個類成員,并且這個類成員顯示的定義了這二個函數(shù)之一。
b. 當(dāng)這個類繼承的基類顯示的定義了這二個函數(shù)之一。
c. 當(dāng)這個類有虛函數(shù)的時候
d. 當(dāng)這個類的繼承鏈中存一個虛基類的時候。

以上四種情況存在時,則一個類的bitwise語義被破壞,這時編譯器會提供上面提到的二個函數(shù)。除些之外,都是按照member-wise 來復(fù)制的,這個復(fù)制的實(shí)現(xiàn)各個編譯器并不一定相同。

C++博大精深,學(xué)了十年,仍感覺是初學(xué)者。從來敢說自己會C++.也可能是用的少的原因

網(wǎng)友評論:“從來敢說”應(yīng)是“從未敢說”,

網(wǎng)友評論:
編譯通過,截圖為證,到此為止

aihe 發(fā)表于 2011-5-15 19:26
aihe老師說的對,就此打住,再費(fèi)那個勁,也不會有結(jié)果的,因?yàn)榫幾g原理明擺著,優(yōu)化是不可能超越基本硬件特征的。就算更改庫函數(shù),強(qiáng)制用匯編優(yōu)化,也省不了幾個字節(jié),并且程序可移植性變差~~~

網(wǎng)友評論:

76樓學(xué)生寫的太精彩了,包含了很多概念應(yīng)用。最終結(jié)果并不在于一個小小的改動就把code縮減幾十字節(jié),主要是這里包含的教育意義!裁唇兄苯訉ぶ,間接尋址。能使用直接尋址的地方一定比使用間接尋址快。

aihe的源程序在keil C上 一個Xdata/idata就使程序代碼縮減近100字節(jié)!這就是直接尋址和指針間接尋址的差別!蚹eil C 還是 COSMIC C 根本沒關(guān)系!

這年頭,誰比誰差?Keil C 有Xdata/ideta ,COSMIC C 相應(yīng)尋址就有@near / @tiny 。
C 編譯器都是以ANSI C為標(biāo)準(zhǔn)的。論功能誰都不差。昨天是誰還在把 Keil C 貶的一無是處,現(xiàn)在是不是又該貶COSMICC 了。(在這種人眼里,除了自己,別人都是一無是處! 一天到晚以貶低別人為快樂。)以為意法 做不出個好的編譯器?貶低意法也快樂 ?

誰說76樓學(xué)生修改的程序可移植性差?123jj 是想說:“意法的程序?qū)懙奶盍,沒有可移植性!?
見圖:



呵,別忘了學(xué)生這個仿COSMIC 源程序首先是在 keilC下通過的,什么意義不用提醒吧。—— ANSIC標(biāo)準(zhǔn)程序,這里沒有idata , Xdata,不用那么仔細(xì)找茬。(不會揪住第一條說事吧,那我把它刪了好了。)

貶低意法很快樂 ?

為何keilC加了一個xdata / idata 說明,就輕易把code 縮減了近 100字節(jié)?——COSMIC C理論上也一樣;修改前后編譯結(jié)果匯編碼的分析比較是真正快樂的事;分析過程中所發(fā)現(xiàn)的東西,學(xué)了十年都不知道。

所以可以這么說,aihe 無意中的這段程序極有價值。幾天學(xué)到的東西,勝讀十年書。——照本宣科講理論有什么意思,講講這段程序所包含的概念有意思多了。
像那種根本不會關(guān)注這種價值的分析研究過程的人,只關(guān)心什么“ keil 不算,這是STM8……”,呵,俺已經(jīng)不關(guān)心這類處處給自己找臺階的事了,——僅從 keilC51 中發(fā)現(xiàn)的這種現(xiàn)象,才真正是讓學(xué)生關(guān)注、興趣投入的地方。
唉,贊嘆:由此知道為什么 年長并沒有用了! 有提升自己的好機(jī)會發(fā)現(xiàn)不了,——時間和生命全耗在 “頭忙著打仗呢!薄罢τ趯ふ襊K目標(biāo)呢!


、、






、

網(wǎng)友評論:LS劉小輩正解!

直接尋址一定比使用間接尋址快!

在少量數(shù)據(jù)移動時,直接尋址指令短一點(diǎn),速度快一點(diǎn),比間接尋址有著天然的優(yōu)勢!

但是,在大量數(shù)據(jù)移動時,直接尋址在速度上是能快一點(diǎn),但代碼庸腫,比間接尋址增加N倍代碼!
并且?guī)缀蹼y以做到同類型數(shù)據(jù)之間的代碼復(fù)制和移植!


這個問題根本不用討論C語言還是C++,你只要用匯編編寫一個移動復(fù)制1000個BYTE數(shù)據(jù)的代碼,不充許用間接尋址,只能用直接尋址,那個代碼量好嚇人啊~~~

網(wǎng)友評論:在代碼的壓縮問題上,俺一向只看匯編,如果C編譯后的代碼,同俺手工寫的差不多大小,俺就認(rèn)為沒有再優(yōu)化的必要了~~~

網(wǎng)友評論:俺也累了,劉小輩,咱們聽aihe老師之言
別費(fèi)那個勁了
就此打住吧
aihe 發(fā)表于 2011-5-15 19:02


網(wǎng)友評論:淡定、淡定
在COSMIC上你那個程序和我那個最終的匯編代碼是一樣的
不知道intel做51時怎么想的,弄那么多的尋址方式,直接尋址就得了,還是Keil不夠智能化,呵呵
轉(zhuǎn)成指針時非得用三字節(jié),還不存在Rx中,指針加1程序也搞得異常復(fù)雜
怪不得PIC等成為后起之秀呢
提醒一下自己,下次用這個程序時要小心了,如果FLASH+RAM+EEPROM超過64K時unsigned int是不夠用的

網(wǎng)友評論:修正一下,超過32K,因?yàn)镾TM207 FLASH的起始地址是8080

瀏覽:(5656)| 評論( 0 )
博文評論

  • 昵 稱:
  • 內(nèi) 容:10~250個字符
  • 驗(yàn)證碼: 驗(yàn)證碼看不清楚?請點(diǎn)擊刷新驗(yàn)證碼
  •                      
  • 博文分類

    熱點(diǎn)博文

    最新博文

    最新評論

    IC電子元件查詢
    IC郵購網(wǎng)電子元件品質(zhì)保障

    色爱av综合网_色女人在线视频_男男gaygays亚洲_日本高清久久一区二区三区
    国产一区二区三区最好精华液| 亚洲午夜久久久久久久久电影网| 久久超碰97人人做人人爱| 另类尿喷潮videofree| 国产精品亚洲第一区在线暖暖韩国| 在线亚洲免费视频| 欧美视频一区二区| 亚洲综合色激情五月| 国产美女精品在线| 久久免费视频网| 日韩亚洲不卡在线| 国产精品黄视频| 性欧美在线看片a免费观看| 国产视频精品免费播放| 久久精品99无色码中文字幕| 亚洲第一精品在线| 欧美日韩中文字幕精品| 午夜精品影院| 亚洲黄色尤物视频| 国产精品久久久久一区二区| 欧美一区日本一区韩国一区| 亚洲精品久久久久| 国产精品一区二区久久国产| 免费日韩成人| 亚洲免费网站| 亚洲午夜在线视频| 亚洲午夜久久久久久久久电影网| 亚洲午夜性刺激影院| 韩国一区二区在线观看| 欧美精品1区2区3区| 日韩亚洲在线观看| 国内综合精品午夜久久资源| 欧美日本在线播放| 久久在线播放| 亚洲免费婷婷| av成人天堂| 黑人一区二区| 国产日产精品一区二区三区四区的观看方式| 久久久久国产精品一区三寸| 亚洲在线视频观看| 日韩亚洲欧美中文三级| 影音国产精品| 国模私拍视频一区| 国产嫩草一区二区三区在线观看| 欧美日韩美女| 老鸭窝91久久精品色噜噜导演| 亚洲尤物在线| 亚洲精品一区二区三区福利| 亚洲第一在线综合网站| 黄色成人在线网站| 国内精品美女在线观看| 国产欧美一区二区精品仙草咪 | 在线视频精品一区| 91久久久久久久久| 在线国产亚洲欧美| 在线观看欧美一区| 亚洲国产高清自拍| 亚洲国产视频直播| 亚洲精品视频在线播放| 亚洲激情影院| 99综合在线| 亚洲网友自拍| 欧美夜福利tv在线| 久久精品国产亚洲一区二区| 欧美在线关看| 裸体一区二区三区| 欧美大尺度在线观看| 欧美日本视频在线| 国产精品久久久久久久久久免费 | 一区二区免费在线视频| 亚洲国产精品久久久久婷婷884| 国产在线视频欧美一区二区三区| 国内精品免费在线观看| 亚洲激情av在线| 亚洲五月六月| 久久av二区| 欧美激情一区二区三区全黄 | 国产亚洲一区二区三区在线观看 | 午夜精品免费视频| 久久激情五月婷婷| 欧美高清一区二区| 国产精品女主播在线观看| 国产一区99| 99re热精品| 久久久久国产免费免费| 欧美日韩伦理在线免费| 国产色爱av资源综合区| 91久久久国产精品| 欧美亚洲一区| 欧美激情成人在线| 国产欧美一级| 日韩一区二区久久| 欧美中文字幕视频在线观看| 欧美激情欧美狂野欧美精品| 国产欧美二区| 亚洲另类春色国产| 久久精品系列| 国产精品高潮呻吟视频| 亚洲第一主播视频| 午夜一级在线看亚洲| 欧美另类一区| 在线精品观看| 久久国产精品99国产| 欧美三级视频| 亚洲国产小视频| 久久精品亚洲| 国产美女精品视频免费观看| 亚洲激情视频网| 久久久精品国产一区二区三区| 欧美日韩精品免费在线观看视频| 黄色亚洲精品| 香蕉乱码成人久久天堂爱免费| 欧美激情日韩| 亚洲国产成人av| 久久蜜臀精品av| 国产日韩欧美综合一区| 亚洲一区二区三区在线观看视频| 欧美国产免费| 亚洲国产黄色片| 老鸭窝毛片一区二区三区| 国产亚洲va综合人人澡精品| 亚洲一区日韩| 国产精品va在线| 亚洲视频在线观看| 欧美日韩成人在线观看| 亚洲第一网站免费视频| 久久精品视频在线| 国产一区二区中文| 久久精品国产亚洲aⅴ| 国产欧美日韩精品专区| 亚洲一线二线三线久久久| 欧美性感一类影片在线播放| 一区二区三区不卡视频在线观看 | 欧美日韩国产欧| 99视频一区二区三区| 欧美激情精品| 一区二区精品在线观看| 欧美日韩精品综合| 亚洲视频观看| 国产日韩在线一区二区三区| 午夜视频一区二区| 国产亚洲一级| 麻豆精品在线播放| 亚洲激情六月丁香| 欧美天天影院| 欧美自拍偷拍| 在线观看中文字幕不卡| 欧美韩日高清| 亚洲一区二区三区涩| 国产一区二区毛片| 欧美成人精品1314www| 99精品视频免费全部在线| 国产精品第三页| 久久久久高清| 99re国产精品| 国产一区二区三区在线观看免费| 久久人91精品久久久久久不卡 | 一个色综合av| 国产欧美精品| 欧美大片在线看| 亚洲午夜性刺激影院| 激情视频一区| 欧美午夜精品电影| 久久久久久国产精品mv| 亚洲毛片在线看| 国产一区二区福利| 欧美巨乳在线| 久久女同互慰一区二区三区| 一本大道久久a久久精品综合| 国产欧美一区二区精品婷婷| 欧美大片一区| 久久黄色网页| 国产精品亚洲а∨天堂免在线| 亚洲男人天堂2024| 欧美成人在线免费观看| 噜噜噜噜噜久久久久久91| 国产精品美女一区二区| 欧美aⅴ一区二区三区视频| 日韩亚洲欧美中文三级| 欧美国产一区在线| 99视频一区二区| 亚洲国产一区二区a毛片| 亚洲国产毛片完整版 | 欧美亚洲第一区| 欧美日韩性视频在线| 国产精品福利久久久| 国产精品一卡二| 久久福利影视| 亚洲一区黄色| 久久一区中文字幕| 中文欧美字幕免费| 亚洲午夜久久久久久久久电影院 | 老司机成人网| 午夜精品美女自拍福到在线| 亚洲精品一级| 亚洲高清自拍| 在线观看中文字幕不卡| 国产日韩一区二区三区在线播放 | 国产亚洲欧美中文| 国产精品福利网|