欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
c51軟復位經(jīng)典分析

c51軟復位經(jīng)典分析



  在電子BBS討論區上溜達,看到一個(gè)有趣的帖子,整個(gè)帖子內容如下:
  純C51復位功能函數:一個(gè)大三學(xué)生,讓人又愛(ài)又怕

  現單列復位部分如下:

main()
{
   unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32};  // 復位代碼
  (*((void (*)())(rst)))();  // 執行上一行代碼,將rst數組當函數調用
}

本來(lái)我告訴他嵌入如下代碼:
clr a
push acc
push acc
reti

  結果他卻玩了前面哪一段,而數組rst[]中的內容恰恰是上面的匯編機器碼,他的做法是將rst數組的數據當作代碼保存,然后采用絕對地址方式指向該數組,將該數組中的代碼當作函數來(lái)運行。居然通過(guò)了!

  我覺(jué)得有問(wèn)題,我說(shuō)即使如此,那絕對地址調用也應該寫(xiě)成(*((void(*)())(&rst)))()才對呀,結果他反駁說(shuō),那樣的話(huà),rst的地址就會(huì )當成參數傳遞給這個(gè)絕對地址函數,而實(shí)際LJMP調用的地址并非rst的地址,而是一個(gè)不確定的地址。于是我按照自己的說(shuō)法嘗試了一下,看看匯編結果,還真的是將rst的地址傳遞給了R1R2,而絕對函數最終LJMP到了
一個(gè)莫名其妙的地址上去了,死翹!

  看來(lái)C真是一匹不容易駕馭的野馬,這個(gè)大三學(xué)生理解力在我之上,我30多歲的人了,干了這么多年還沒(méi)他的境界呢,唉,人家才學(xué)了幾天啊,翻了幾天書(shū)就這么厲害了,服了!

l 首先分析帖子的C語(yǔ)言代碼
  第一句定義一個(gè)數組rst[],數組內數據就是完成復位功能的匯編機器碼,具體對應關(guān)系
為:clr a == 0xe4、push acc == 0xc0,0xe0、reti ==0x32
  第二句是一個(gè)函數指針的用法,函數指針用法稍微有點(diǎn)復雜,可參看本人著(zhù)的書(shū),
,以
下為快速入門(mén)講解。

  定義一個(gè)返回值是空函數指針的定義形式如下:
    void (*p) ( )
當把函數指針賦值后,就能通過(guò)函數指針調用函數,調用形式如下,
    (*p) ( );
或等價(jià)的簡(jiǎn)化形式:
    p ( );
假設rst就是函數指針,則如下調用形式就可以令單片機復位再起。
   (*rst ) ( );   
但可惜,rst不是函數指針,而是數組名,雖然兩者都是地址,但不可直接調用數組名。
如同把char型變量a賦值給int型變量b,(int) 表示強制類(lèi)型轉換:
   b = (int) a
函數指針的強制類(lèi)型轉換公式如下(C語(yǔ)言的哲學(xué)是定義形式和使用一致):
   (  (void (*)()  ) rst  
這樣經(jīng)過(guò)轉換后的rst就可以當作函數指針使用了,簡(jiǎn)單的調用形式如下:
#define  K     (  (void (*)( )  ) rst
  (*K) ( )
或:
  (     * (  void (*)( )  )rst      ) ( );
這樣的語(yǔ)句就完成復位再啟功能了。類(lèi)型轉換符()的優(yōu)先級跟指針運算符*的優(yōu)先級相同,
二者的結合方向是自右至左,所以上述語(yǔ)句就能完成復位功能了。保險起見(jiàn)有些程序員常
常喜歡再加個(gè)括號:
#define  K     (   (  (void (*)( )  ) rst   )
  (*K) ( )

  (     *(   (  void (*)( )  )rst   )    ) ( );

由于沒(méi)有輸入參數,上述復位代碼更嚴謹的寫(xiě)法是:  
#define  K     (   (  (void (*)(void )  ) rst   )
  (*K) ( )

  (     *(   (  void (*)(void )  )rst   )    ) ( );

關(guān)于帖子作者的解釋
  千萬(wàn)不要犯“&rst”形式的錯誤,對于一維數組而言,數組名rst就代表地址。以下二者等
價(jià),更常用的是等式左邊的形式:
  rst == &rst[0]
  整個(gè)函數指針無(wú)所謂參數傳遞,只是把rst當作程序執行地址調用而已,那個(gè)學(xué)生的解釋也
有問(wèn)題。
  還有一點(diǎn)必須提及,不是說(shuō)能通過(guò)編譯,甚至生成正確代碼,就表示某語(yǔ)句一定是對的。
對很復雜的語(yǔ)句,要考慮到編譯器不嚴格甚至出錯的可能性。

  哈佛結構和一個(gè)蠕蟲(chóng)病毒
  請注意,定義數組rst[]時(shí)用了關(guān)鍵字code,這是C51特有的關(guān)鍵字,意味著(zhù)把數組定義到程序空間。標準C是沒(méi)有關(guān)鍵字code的。

  哈佛結構和普林斯頓結構:
哈佛結構——程序空間和存儲空間分開(kāi)的。C51算是不太嚴格的哈佛結構——雖地址線(xiàn)分開(kāi),但數據線(xiàn)沒(méi)有分開(kāi)。DSP是增強的哈佛結構。
  PC電腦上奔騰CPU是普林斯頓結構——數據空間和程序空間統一編址。
  如果數組rst[]數據的匯編機器碼是刪除文件的機器碼,這算不算是病毒?
  曾經(jīng)流行過(guò)一種蠕蟲(chóng)病毒,其發(fā)作機理采取的就是將惡意代碼保存成文本文件,然后通過(guò)指針調用執行這個(gè)文本,很多殺毒程序也不會(huì )查詢(xún)文本文件。
  程序也罷,數據也罷都是二進(jìn)制形式,如果數據空間和程序空間是統一編碼的, 數據當然可以當作程序運行。
  在這一點(diǎn)上,相對而言,哈佛結構的CPU安全性會(huì )好一點(diǎn)點(diǎn)。但嵌入式應用少有病毒,一般不用關(guān)心。

單片機復位的更好方法
帖子中匯編語(yǔ)言解釋如下:
clr a                   //清除ACC=0
push acc                //壓0到堆?!?位
push acc                //再壓0到堆?!?位
reti                        //返回到0地址,從而執行。

帖子作者的這種復位方法比較麻煩,更加簡(jiǎn)單的復位寫(xiě)法是(摘自《C缺陷與陷阱》):
  (     * (  void (*)( )  )0      ) ( );
本句的分析方法同上,但更加精煉,沒(méi)有多余的匯編語(yǔ)句。

  上述復位的方法可稱(chēng)為軟件復位。
  軟件復位跟真正上電復位有很大差別:上電復位時(shí)大部分寄存器都有確定的復位值;軟件復位則只相當于從0地址開(kāi)始執行而已,寄存器不會(huì )變?yōu)榇_定的復位值。
  如果用戶(hù)要編程實(shí)現上電復位這種情況,在程序中不要踢看門(mén)狗即可。大部分單片機都有看門(mén)狗吧。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
51系列單片機的軟件復位方法
C語(yǔ)言數組當參數傳遞
指針與數組
神一般的C語(yǔ)言指針,你看懂多少?
【轉】typedef int (init
C語(yǔ)言系列
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久