www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > > 程序員寫(xiě)個(gè)解
[導(dǎo)讀]從匯編角度來(lái)說(shuō),如果“test %al, %al”能改成“test %0x1, %al”就沒(méi)有匪夷所思的問(wèn)題了,如此一來(lái)應(yīng)該會(huì)降低CPU的效率,畢竟執(zhí)行指令還需要一個(gè)立即數(shù),我沒(méi)搞過(guò)編譯器也沒(méi)設(shè)計(jì)過(guò)CPU,純屬瞎猜,能搞編譯器的家伙都是大牛的存在,咱們吃瓜的參合個(gè)啥!

上一篇文章《C語(yǔ)言bool占用4個(gè)字節(jié)?匯編之下無(wú)秘密|帶你看extern》分析在C99標(biāo)準(zhǔn)下bool類(lèi)型占用1Byte,而不是1bit,C語(yǔ)言 不存在內(nèi)存長(zhǎng)度小于8bit的數(shù)據(jù)類(lèi)型,思考:

1、如果bool類(lèi)型高7bit不是0,使用bool類(lèi)型是否出現(xiàn)匪夷所思的結(jié)果?

2、執(zhí)行if判斷bool類(lèi)型時(shí),它判斷的是所有8比特?還是最低比特?

接下來(lái)我分享一個(gè)奇特的案例現(xiàn)象,并在從反匯編角度去解釋現(xiàn)象產(chǎn)生原因。

1. 俄羅斯轉(zhuǎn)輪

玩?zhèn)€勇敢者的賭槍游戲——俄羅斯轉(zhuǎn)輪。

左輪手槍彈槽篩入一顆子彈,快速旋轉(zhuǎn)彈槽,合上彈槽,朝著對(duì)方腦袋開(kāi)槍?zhuān)钕聛?lái)的勝利。接下來(lái)友請(qǐng)賭槍游戲必勝客“燕雙鷹”。

燕雙鷹:“我有個(gè)習(xí)慣,會(huì)殺死向自己開(kāi)槍的人,哪怕他的槍里沒(méi)有子彈……”

我:“等等燕大俠,沒(méi)搶、沒(méi)搶。解放了70年咯,1966年在大會(huì)堂玻璃被子彈擊穿事件后,周總理就下達(dá)指令全民禁槍、民眾自愿上繳槍械?!?/span>

燕雙鷹:“那為什么請(qǐng)我出場(chǎng)?”

我:“21世紀(jì)國(guó)家科研、資本家壓榨都講成本,沒(méi)有槍械,可以模擬呀。自動(dòng)駕駛不一定都需要先造車(chē)再去馬路上跑,完全能建立3D場(chǎng)景,在游戲虛擬環(huán)境下訓(xùn)練自動(dòng)駕駛算法。同樣賭槍游戲也能模擬。

“子彈放在8bit寄存器里,寄存器相當(dāng)于彈槽,最低比特相當(dāng)于蓄勢(shì)待發(fā)的子彈。下面是游戲的源代碼?!?/span>


傳入0:表示搶里沒(méi)有子彈。

傳入1:表示子彈在第1激發(fā)位置。

傳入2:表示子彈在第2激發(fā)位置。

傳入4:表示子彈在第3激發(fā)位置。


燕雙鷹:“明白,來(lái)~咱們弄點(diǎn)刺激的,隨機(jī)放入2顆子彈如何,編劇從來(lái)沒(méi)允許賭搶上輸過(guò)?!?/span>

我:“大俠且慢,暖男郭先生說(shuō)沖動(dòng)是魔鬼,咱們1顆子彈試試水?!?/span>

篩入1顆子彈,子彈落入第2激發(fā)位置,扣動(dòng)扳機(jī),屏幕上顯示“false:燕雙鷹贏”。燕雙鷹臉上漏出招牌式微笑。

下一刻屏幕緊跟著輸出“true:Bang 燕雙鷹你輸了”,燕雙鷹眉頭顯出深深的“川”字紋。

各位看官,你能想到燕雙鷹中彈原因嗎?當(dāng)然,如果你能保證絕對(duì)不會(huì)往布爾類(lèi)型傳遞0/1以外的值,本文不用繼續(xù)往下讀。

all: @gcc bool-char.c -g @objdump a.out -S > a.dis @./a.out 0 @./a.out 1 @./a.out 2 @./a.out 3

2. 匯編解釋

接下來(lái)解釋燕雙鷹為什么會(huì)輸。

同樣的代碼在x86、ARM、mips架構(gòu)下用gcc編譯,執(zhí)行結(jié)果都一樣,至于匯編我只解釋x86架構(gòu)下的指令。

兩條件表達(dá)式的匯編都差不多,唯一區(qū)別是第一條多一個(gè)異或指令。


movzbl -0x9(%rbp),%eax:以4Byte方式載入數(shù)據(jù)到eax寄存器,eax是32bit寄存器,eax存儲(chǔ)的是彈槽子彈位置。

test %al, %al:al寄存器的值和它自己“與”操作,al是eax的低8bit寄存器。只要al寄存器8bit不全為0,則返回真。

test指令和and指令都是執(zhí)行“與”操作,不過(guò)test指令會(huì)影響3個(gè)標(biāo)志位:SF(執(zhí)行后數(shù)據(jù)的正負(fù))、ZF(執(zhí)行后結(jié)果是否為0)、PF(執(zhí)行后二進(jìn)制1的個(gè)數(shù)是否為偶數(shù)),and指令不會(huì)修改他們, 本文關(guān)注的是ZF標(biāo)志位。

xor $0x1,%eax:僅對(duì)eax寄存器的最低比特執(zhí)行異或。

C代碼“if(!a)”的感嘆號(hào)“!”被編譯器翻譯成xor和test的組合。注意到了嗎,只要eax不是0或1,兩條指令都會(huì)執(zhí)行。

2.1. 執(zhí)行if(!a)

如果eax=0x00,則xor結(jié)果eax=0x01;test返回真

如果eax=0x01,則xor結(jié)果eax=0x00;test返回假

如果eax=0x02,則xor結(jié)果eax=0x03;test返回

2.2. 執(zhí)行if(a)

如果eax=0x00,test返回假

如果eax=0x01,test返回真

如果eax=0x02,test返回

3. 小白才寫(xiě)得出的代碼

看官或許會(huì)想:“正常情況誰(shuí)會(huì)這么寫(xiě)例子上的垃圾代碼,往bool傳遞0/1以外的數(shù)據(jù),八成是作者為了水文章瞎弄文案?!?/span>

“No No No?!?/span>

6年前我曾今寫(xiě)過(guò)一個(gè)C函數(shù),函數(shù)需要傳遞bool類(lèi)型“指針”。在同事眼里:“布爾類(lèi)型嘛,懂~,老熟人咯。”

于是,他強(qiáng)制轉(zhuǎn)換char為bool,向我的函數(shù)傳遞變量指針。

絕大多數(shù)C語(yǔ)言學(xué)習(xí)者的實(shí)操平臺(tái)要么是Keil C51、要么是Trubo C,兩個(gè)編譯環(huán)境都使用C89標(biāo)準(zhǔn),按照C89的套路,bool類(lèi)型通常都是重新定義char得來(lái)(typedef char bool),殊不知bool類(lèi)型已經(jīng)被C99正式收編,GCC也給它名份,成了C語(yǔ)言家族的第9房小妾(其他妻妾包括char、short、int、long、float、double、void、指針)。


								
void fun(bool *a){ if (!*a) { printf("false\r\n"); } if (*a) { printf("true\r\n"); }}int main(int argc, char **argv) { char in = 2;  fun((bool*)&in); return 0;}

若同事規(guī)規(guī)矩矩的向布爾類(lèi)型賦值0(false)或1(true)還好,可誰(shuí)曾想到他某次傳遞一個(gè)2進(jìn)去,一個(gè)表達(dá)式憑什么既可能是true、也同時(shí)是false呢?

$ ./a.out falsetrue

猜測(cè)同事把布爾類(lèi)型和布爾表達(dá)式搞混了:

布爾類(lèi)型:只觀察最低比特

布爾表達(dá)式:非0即是真。


4. 指令修改

從匯編角度來(lái)說(shuō),如果“test %al, %al”能改成“test %0x1, %al”就沒(méi)有匪夷所思的問(wèn)題了,如此一來(lái)應(yīng)該會(huì)降低CPU的效率,畢竟執(zhí)行指令還需要一個(gè)立即數(shù),我沒(méi)搞過(guò)編譯器也沒(méi)設(shè)計(jì)過(guò)CPU,純屬瞎猜,能搞編譯器的家伙都是大牛的存在,咱們吃瓜的參合個(gè)啥!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉