• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 0  文章 - 0  trackbacks - 0
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿

            文章檔案(4)

            c 相關

            friends

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 777
            • 排名 - 2474

            最新隨筆

            最新評論

            c51軟復位,經典,分析透徹

            ........注:轉貼...........

            從單片機指針說到黑客程序


            2004年7月的一天,在電子BBS討論區上溜達,看到一個有趣的帖子,整個帖子內容如下:

            純C51復位功能函數:一個大三學生,讓人又愛又怕

            現單列復位部分如下:

            main()

            {

            ?? unsigned char code rst[]={0xe4,0xc0,0xe0,0xc0,0xe0,0x32};??// 復位代碼

            ?? (*((void (*)())(rst)))();??// 執行上一行代碼,將rst數組當函數調用

            }

            本來我告訴他嵌入如下代碼:

            clr a

            push acc

            push acc

            reti

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

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

            看來C真是一匹不容易駕馭的野馬,這個大三學生理解力在我之上,我30多歲的人了,干了
            這么多年還沒他的境界呢,唉,人家才學了幾天啊,翻了幾天書就這么厲害了,服了
            定義一個返回值是空函數指針的定義形式如下:

            void (*p) ( )

            當把函數指針賦值后,就能通過函數指針調用函數,調用形式如下,

            ??????(*p) ( );

            或等價的簡化形式:

            p ( );

            假設rst就是函數指針,則如下調用形式就可以令單片機復位再起。

            (*rst ) ( );??

            但可惜,rst不是函數指針,而是數組名,雖然兩者都是地址,但不可直接調用數組名。

            如同把char型變量a賦值給int型變量b,(int) 表示強制類型轉換:

            b = (int) a

            函數指針的強制類型轉換公式如下(C語言的哲學是定義形式和使用一致):

            (??(void (*)()??) rst

            這樣經過轉換后的rst就可以當作函數指針使用了,簡單的調用形式如下:

            #define??K???? (??(void (*)( )??) rst

            (*K) ( )

            或:

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

            這樣的語句就完成復位再啟功能了。類型轉換符()的優先級跟指針運算符*的優先級相同,
            二者的結合方向是自右至左,所以上述語句就能完成復位功能了。保險起見有些程序員常
            常喜歡再加個括號:

            #define??K???? (?? (??(void (*)( )??) rst?? )

            (*K) ( )



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

            posted on 2006-10-26 20:33 天性如此 閱讀(129) 評論(0)  編輯 收藏 引用
            久久久久无码精品国产app| 久久久久亚洲av无码专区| 99久久99这里只有免费的精品| 色天使久久综合网天天| 久久最新精品国产| 欧美伊香蕉久久综合类网站| 久久综合88熟人妻| 久久精品人人做人人妻人人玩| 日本久久久久亚洲中字幕| 人妻无码αv中文字幕久久琪琪布| 国内精品久久久久影院老司| 一日本道伊人久久综合影| 亚洲精品97久久中文字幕无码| 欧美精品丝袜久久久中文字幕 | 国内精品久久久久久麻豆| 欧美综合天天夜夜久久| 久久99精品久久久久久9蜜桃| 久久久久国产视频电影| 一本久道久久综合狠狠躁AV| 人妻无码精品久久亚瑟影视| 亚洲国产精品无码久久久蜜芽| 久久久噜噜噜久久中文福利| 久久精品国内一区二区三区| 一本久久久久久久| 亚洲精品无码久久毛片| 欧美一区二区三区久久综合| 久久精品国产亚洲欧美| 久久久久九九精品影院| 国内精品久久久久影院薰衣草| 国产三级久久久精品麻豆三级| 久久高清一级毛片| 精品国产VA久久久久久久冰 | 久久综合五月丁香久久激情| 亚洲精品乱码久久久久久按摩 | 久久亚洲AV成人无码国产| 999久久久国产精品| 国产69精品久久久久观看软件| 久久99免费视频| 无码伊人66久久大杳蕉网站谷歌| 亚洲成色999久久网站| 综合网日日天干夜夜久久|