chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式匯編中g(shù)o to到c代碼label最簡單的用法

Linux閱碼場 ? 來源:CSDN ? 作者:dog250 ? 2021-04-04 17:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

越來越多的工作現(xiàn)如今都交給了編譯器,甚至連動態(tài)代碼修改的數(shù)據(jù)組織這種事都交給了編譯器。gcc提供了一個特性用于嵌入式匯編,那就是asm goto,其實(shí)這個特性沒有什么神秘之處,就是在嵌入式匯編中g(shù)o to到c代碼的label,其最簡單的用法如下(來自gcc的文檔):

d0f90b8c-8cdd-11eb-8b86-12bb97331649.png

asm goto其實(shí)就是在outputs,inputs,registers-modified之外提供了嵌入式匯編的第四個“:”,后面可以跟一系列的c語言的label,然后你可以在嵌入式匯編中g(shù)o to到這些label中一個。然而使用asm goto可以巧妙地將“一個大家都能想到的點(diǎn)子”規(guī)范化,就是說你只需要調(diào)用一個統(tǒng)一的接口--一個宏,編譯器就將你想實(shí)現(xiàn)的東西給實(shí)現(xiàn)了,要不然代碼寫起來會很麻煩,這點(diǎn)上,編譯器不嫌麻煩。這一個大家都能想出的點(diǎn)子的由來還得從內(nèi)核的效率說起。

以下的代碼來自lwn的《Jump label》:

d11a53be-8cdd-11eb-8b86-12bb97331649.png

即使有了unlikey優(yōu)化,既然有if判斷,cpu的分支預(yù)測就有可能失敗,再者do_trace在代碼上離if這么近,即使編譯器再聰明,二進(jìn)制代碼的do_trace也不會離前面的代碼太遠(yuǎn)的,這樣由于局部性原理和cpu的預(yù)取機(jī)制,do_trace的代碼很有可能就被預(yù)取入了cpu的cache,就算我們從來不打算trace代碼也是如此。

我們需要的是如果不開啟trace,那么do_trace永遠(yuǎn)不被欲取或者被預(yù)測,唯一的辦法就是去掉if判斷,永遠(yuǎn)不調(diào)用goto語句,像下面這樣:

d16ccc02-8cdd-11eb-8b86-12bb97331649.png

在運(yùn)行時修改載入內(nèi)存的二進(jìn)制代碼就是我們大家都能想到的點(diǎn)子,就是說在運(yùn)行的時候當(dāng)我們知道trace_foo_enabled在某一時刻被設(shè)置為0的時候,我們動態(tài)的將二進(jìn)制代碼修改掉,將if代碼段去掉,這樣一個分支預(yù)測就不存在了,而且trace_foo_enabled這一個變量也不需要再被訪問了(該變量在內(nèi)存中,訪問它肯定會涉及l(fā)oad/flush cache的動作,為了一個很可能沒有用的變量操作cache很不值)。提前要說的是,我們可以使用這種方式去掉所有的分支預(yù)測,然而這并不可取,因?yàn)槌绦蚴莿討B(tài)運(yùn)行的,很多用于判斷的變量值都是根據(jù)程序的執(zhí)行瞬息萬變,正是這種根據(jù)判斷結(jié)果采取不同動作的機(jī)制給與了程序靈活性,如果每當(dāng)我們確定一個值時就修改二進(jìn)制代碼取消分支預(yù)測的話,其本身的開銷將會遠(yuǎn)遠(yuǎn)大于分支預(yù)測的開銷,更重要的是,緊接著那個值又變化了,我們不得不再次修改二進(jìn)制代碼,這期間要訪問那個變量好幾次。所以,只有在我們確定不經(jīng)常變化的變量的判斷上才能用這種方式取消分支預(yù)測,而像trace與否的判斷正好符合我們的需求。

gcc編譯器提供了asm goto的機(jī)制來滿足我們的需求,使得我們可以在asm goto的基礎(chǔ)上構(gòu)建出一個叫做jump label的東西。下面的代碼段說明了jump label的用法和原理:

d1e01e96-8cdd-11eb-8b86-12bb97331649.png

標(biāo)號0僅僅執(zhí)行一個nop,不涉及cache,后面的pushsection保存現(xiàn)有的section,很多情況下當(dāng)前的section就是text,然后定義一個“表”,表中有兩個元素:0b和trace#NUM,其實(shí)就是兩個標(biāo)號,在asm goto機(jī)制中,標(biāo)號還可以更多,它們在嵌入式匯編的最后一個“:”后面依次排布。這些標(biāo)號就是供選擇的標(biāo)號,執(zhí)行流將跳入其中的一個標(biāo)號處,具體跳到哪一個就看當(dāng)前的二進(jìn)制代碼被修改成了“跳到哪一個”,因此asm goto為我們做的僅僅是提供一個地方(一個“:”)供我們將label傳入,保存了一系列的表還是需要我們的c代碼邏輯--jump label實(shí)現(xiàn),這些表(其實(shí)就是一系列的三元組)方便我們根據(jù)這些表來修改運(yùn)行中的二進(jìn)制代碼,最終修改二進(jìn)制代碼還是要由我們自己寫代碼完成的。

有了這個asm goto以及我們jump label代碼的支持,內(nèi)核對于是否trace這種小事就再也不用愁了(使用中的kernel一般是不用trace的,只有在出了問題以后或者調(diào)試內(nèi)核時才使用trace,因此在主代碼中加入“是否trace”的判斷實(shí)在是一種沉重的負(fù)擔(dān)),如果對于某一個函數(shù)不需要trace,內(nèi)核只需要執(zhí)行一個操作將asm goto附近的代碼改掉即可,比如改稱下面這樣:

d1fcdf54-8cdd-11eb-8b86-12bb97331649.png

如果需要trace,那么就改成:

d227dd30-8cdd-11eb-8b86-12bb97331649.png

這一切在kernel中的用法如下:

d246edba-8cdd-11eb-8b86-12bb97331649.png

第一行的“1”是一個標(biāo)號,該標(biāo)號后的代碼執(zhí)行的內(nèi)容就是nop-第二行,第三行重新開始了一個section,這樣的意義很大,下面的三元組:[instruction address] [jump target] [tracepoint key]的二進(jìn)制代碼就不會緊接著標(biāo)號1(nop)了,這個三元組就是jump label機(jī)制的核心,指示了所有可能跳轉(zhuǎn)到的標(biāo)號,這里的技巧在于標(biāo)號1,標(biāo)號1也作為一個合法的可能跳轉(zhuǎn)到的標(biāo)號存在,和標(biāo)號label是并列的,由于pushsection和popsection的存在,上面的代碼匯編結(jié)果看起來是下面這樣:

d262c2c4-8cdd-11eb-8b86-12bb97331649.png

如果啟用了trace,那么只需要將標(biāo)號1修改成標(biāo)號label就可以了:

d2b347f8-8cdd-11eb-8b86-12bb97331649.png

內(nèi)核之所以能夠找到需要修改代碼的地址,就是借助于上面說的那個三元組(instruction address,jump target,tracepoint key),其中instruction address就是這個地址,在linux的JUMP LABEL機(jī)制中,它固定為標(biāo)號1,也就是nop的標(biāo)號,如果不啟用trace,那么直接執(zhí)行nop,如果啟用了trace,那么將nop修改為jmp label即可,如果后來又禁用了trace,只需將它再次修改成三元組中的標(biāo)號1即可,這一切過程中,三元組本身是不會改變的。注意,三元組中的tracepoint key在jump label機(jī)制中并沒有什么實(shí)質(zhì)的意義,它僅僅是為了組織kernel中“是否trace”變量用的,所有的“是否trace”變量組織成一個鏈表,鏈表的每一個節(jié)點(diǎn)下面掛著另一個子鏈表,該子鏈表中元素是所有使用這個“是否trace”變量的代碼環(huán)境,包括代碼的地址,標(biāo)號的地址等。

下面看一下kernel對于JUMP_LABEL的實(shí)現(xiàn)框架。首先看一下三元組的數(shù)據(jù)結(jié)構(gòu):

d2f035e6-8cdd-11eb-8b86-12bb97331649.png

其次一個比較重要的數(shù)據(jù)結(jié)構(gòu)是一個key節(jié)點(diǎn),表示一個“是否trace”的變量:

d33b7420-8cdd-11eb-8b86-12bb97331649.png

啟用一個trace意味著需要將一個key(類似于trace_foo_enabled)設(shè)置為1,然后修改所有判斷該key的代碼附近的二進(jìn)制代碼:

d3842de6-8cdd-11eb-8b86-12bb97331649.png

d3b8bc78-8cdd-11eb-8b86-12bb97331649.png

以上就是使用asm goto實(shí)現(xiàn)的jump label,在2.6.37內(nèi)核中被引入。

附:.section以及.previous

在匯編語言中使用.section和.previous指令可以將它們之間的代碼編譯到不同的section中,也就是不緊接著.section上面的代碼。linux kernel中的異常處理就是用這兩個偽指令實(shí)現(xiàn)的,定義了一個叫做fix的section和一個叫做ex_table的section,可能出現(xiàn)exception的代碼用一個標(biāo)號表示,ex_table中保存了一些二元組(出現(xiàn)異常代碼的標(biāo)號,異常處理程序的標(biāo)號),異常處理程序在fix這個section中,這樣雖然代碼看起來是下面這樣:

d3f8c854-8cdd-11eb-8b86-12bb97331649.png

然而編譯器會將fix和ex_table放到離text很遠(yuǎn)的地方的,這樣cpu預(yù)取時就不會將fix或者ex_table的代碼預(yù)取到執(zhí)行cache了,只有在發(fā)生異常的時候才會使用fix和ex_table,而發(fā)生異常畢竟是一種罕見現(xiàn)象,這就是一種優(yōu)化。

原文標(biāo)題:asm goto與JUMP_LABEL

文章出處:【微信公眾號:Linuxer】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4924

    瀏覽量

    72384
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1665

    瀏覽量

    50908

原文標(biāo)題:asm goto與JUMP_LABEL

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    嵌入式需要掌握哪些核心技能?

    : 1)C語言與底層編程 核心地位:C語言是嵌入式開發(fā)的基石,需精通指針操作、內(nèi)存管理、位運(yùn)算,直接操控硬件資源。 延伸技能:C++用于復(fù)雜項(xiàng)目架構(gòu)設(shè)計(jì),
    發(fā)表于 10-21 16:25

    嵌入式達(dá)到什么水平才能就業(yè)?

    工具定位問題具備嵌入式軟件模塊化設(shè)計(jì)能力:能按功能劃分代碼模塊,編寫規(guī)范的頭文件與源文件,實(shí)現(xiàn)模塊間低耦合調(diào)用會使用Git 進(jìn)行版本管理:能提交代碼、解決沖突、回滾版本,熟悉敏捷開發(fā)流程
    發(fā)表于 09-15 10:20

    嵌入式從入門進(jìn)階,怎么學(xué)?

    嵌入式從入門進(jìn)階,怎么學(xué)? 嵌入式學(xué)習(xí)的核心是 “軟硬結(jié)合的技術(shù)壁壘”,科學(xué)分層才能高效突破。以下是從入門高階的精簡路線,幫你避開彎路: 1、基礎(chǔ)奠基層:構(gòu)建技術(shù)底座
    發(fā)表于 09-02 09:44

    入行嵌入式應(yīng)該怎么準(zhǔn)備?

    知識: 一、C/C++編程C/C++是嵌入式系統(tǒng)開發(fā)中最常用的編程語言。熟練掌握C/
    發(fā)表于 08-06 10:34

    嵌入式系統(tǒng),F(xiàn)LASH 的程序代碼必須搬到 RAM 運(yùn)行嗎?

    嵌入式系統(tǒng)里,F(xiàn)LASH 的程序代碼并非必須搬到 RAM 運(yùn)行,這得由硬件配置、實(shí)際性能需求和應(yīng)用場景共同決定。就像很多低端單片機(jī),無論是依賴片內(nèi) Flash 還是外掛的 SPI
    的頭像 發(fā)表于 08-06 10:19 ?1021次閱讀
    <b class='flag-5'>嵌入式</b>系統(tǒng)<b class='flag-5'>中</b>,F(xiàn)LASH <b class='flag-5'>中</b>的程序<b class='flag-5'>代碼</b>必須搬到 RAM <b class='flag-5'>中</b>運(yùn)行嗎?

    Linux嵌入式和單片機(jī)嵌入式的區(qū)別?

    : 單片機(jī)嵌入式 :開發(fā)環(huán)境相對簡單,通常使用C語言或匯編語言進(jìn)行編程,開發(fā)工具包括Keil、IAR等。 Linux嵌入式 :開發(fā)環(huán)境較
    發(fā)表于 06-20 09:46

    聚徽智控——從嵌入式邊緣計(jì)算:平板工控電腦的技術(shù)進(jìn)化論

    在工業(yè)數(shù)字化轉(zhuǎn)型的浪潮,平板工控電腦作為核心終端設(shè)備,正經(jīng)歷從嵌入式系統(tǒng)邊緣計(jì)算架構(gòu)的范式革命。這一進(jìn)化不僅重塑了設(shè)備的技術(shù)形態(tài),更推動了工業(yè)互聯(lián)從“數(shù)據(jù)采集”向“智能決策”的跨越。本文將從技術(shù)
    的頭像 發(fā)表于 06-13 13:48 ?474次閱讀

    Python在嵌入式系統(tǒng)的應(yīng)用場景

    你想把你的職業(yè)生涯提升到一個新的水平?Python在嵌入式系統(tǒng)中正在成為一股不可缺少的新力量。盡管傳統(tǒng)上嵌入式開發(fā)更多地依賴于CC++語言,Python的優(yōu)勢在于其簡潔的語法、豐富的
    的頭像 發(fā)表于 03-19 14:10 ?1023次閱讀

    嵌入式系統(tǒng)代碼優(yōu)化與壓縮技術(shù)

    在當(dāng)今數(shù)字化時代,嵌入式系統(tǒng)廣泛應(yīng)用于各個領(lǐng)域,從智能家居設(shè)備工業(yè)控制系統(tǒng),從汽車電子可穿戴設(shè)備,它們無處不在。而在嵌入式系統(tǒng)開發(fā),
    發(fā)表于 02-26 15:00

    I2C總線在嵌入式系統(tǒng)的應(yīng)用

    在現(xiàn)代電子設(shè)計(jì)嵌入式系統(tǒng)扮演著越來越重要的角色。這些系統(tǒng)通常需要與多種外圍設(shè)備進(jìn)行通信,以實(shí)現(xiàn)數(shù)據(jù)的輸入和輸出。I2C總線作為一種多主機(jī)、多從機(jī)的串行通信協(xié)議,因其簡單、靈活和高效
    的頭像 發(fā)表于 01-17 15:30 ?1028次閱讀

    如何提高嵌入式代碼質(zhì)量?

    并提升代碼質(zhì)量。 遵循良好的軟件工程實(shí)踐 良好的軟件工程實(shí)踐是提高代碼質(zhì)量的基礎(chǔ),特別是在嵌入式系統(tǒng)更為重要。以下是幾個關(guān)鍵點(diǎn): 1. 模塊化設(shè)計(jì):將系統(tǒng)分解為獨(dú)立的模塊,每
    發(fā)表于 01-15 10:48

    新手怎么學(xué)嵌入式?

    基本的概念。嵌入式系統(tǒng)是一種將計(jì)算機(jī)技術(shù)嵌入特定設(shè)備的系統(tǒng),它通常具有特定的功能和有限的資源。你需要學(xué)習(xí)一些計(jì)算機(jī)基礎(chǔ)知識,如數(shù)據(jù)結(jié)構(gòu)、操作系統(tǒng)、計(jì)算機(jī)組成原理等。這些知識將幫助你
    發(fā)表于 12-12 10:51

    什么是嵌入式人工智能

    嵌入式人工智能是指將人工智能技術(shù)應(yīng)用于嵌入式系統(tǒng)的一種技術(shù)。嵌入式系統(tǒng)是嵌入其他設(shè)備或系統(tǒng)
    的頭像 發(fā)表于 12-11 09:23 ?1338次閱讀
    什么是<b class='flag-5'>嵌入式</b>人工智能

    HAL庫在嵌入式系統(tǒng)的應(yīng)用

    HAL庫(Hardware Abstraction Layer Library,硬件抽象層庫)在嵌入式系統(tǒng)扮演著至關(guān)重要的角色。以下是HAL庫在嵌入式系統(tǒng)的應(yīng)用的分析: 一、HAL
    的頭像 發(fā)表于 12-02 11:32 ?2716次閱讀

    mmc卡在嵌入式系統(tǒng)的使用

    隨著科技的發(fā)展,嵌入式系統(tǒng)在我們的日常生活扮演著越來越重要的角色。從智能手機(jī)到家用電器,再到工業(yè)控制系統(tǒng),嵌入式系統(tǒng)無處不在。存儲設(shè)備作為嵌入式系統(tǒng)
    的頭像 發(fā)表于 11-25 09:58 ?1552次閱讀