日本在线www-日本在线播放一区-日本在线不卡免费视频一区-日本在线不卡视频-成人影院久久久久久影院-成人影院一区二区三区

最新廣告
關注中國自動化產業發展的先行者!
工業智能邊緣計算2025年會
CAIAC 2025
2025工業安全大會
OICT公益講堂
當前位置:首頁 >> 案例 >> 案例首頁

案例頻道

一種基于Gcc的控制編程語言編譯方案
  • 企業:控制網     領域:儀器儀表     行業:建筑樓宇    
  • 點擊數:2138     發布時間:2008-06-29 09:54:27
  • 分享到:
 
    胡志遠(1982-)
男,信息產業部電子六所碩士研究生,(華北計算機系統工程研究所,北京  100083),計算機應用技術專業,在讀。現于北京和利時系統工程公司實習,研究方向為工業控制語言編譯。

摘要:
Gcc是公認的功能強大的開源編譯器。本文介紹了一種利用Gcc實現控制器編程語言編譯功能的方案。

關鍵詞:
Gcc;編譯

Abstract:
It is well-known that Gcc(Gnu C Compiler)is a powerful “Open Source” compiler. In this paper, we introduce the method to compile the control languages using Gcc.

Key words:
  Gcc;compile

1  引言

    用控制編程語言編寫的算法經過編譯后,通常都會下裝到控制器中由控制器軟件調度執行,而不是由操作系統直接調度執行。因此,對編譯生成的二進制格式有特殊要求。本文將介紹一種利用Gcc編譯器輔助生成項目所需的特殊格式二進制目標文件的方案。

2  概述

  整體編譯方案如圖1所示。



圖 1  組態整體編譯方案圖

    首先,控制語言經過編譯產生邏輯上等價的C代碼,然后,編譯模塊對C文件進行編譯處理生成所需特殊格式目標文件。

    編譯模塊會借助Gcc工具鏈對C文件進行編譯連接等處理。實現方案中關鍵部分有:

    (1)通過修改匯編指令BL,實現函數間接地址跳轉。

    (2)通過使用Gcc的擴展語法__attribute__,輔助鏈接腳本控制鏈接過程,利用Gcc工具鏈中鏈接器ld對.o文件進行鏈接實現變量指定地址分配。

    (3)通過使用Gcc工具鏈中objdump工具,取得.o文件中重定位信息。

    (4)通過使用Gcc工具鏈中readelf工具,提取.l文件中機器碼信息以及部分重定位信息。

3  關鍵技術介紹



圖 2   編譯模塊處理流程

    上圖展示了編譯模塊內部處理方案。下面以圖2中所示處理流程為序,介紹編譯過程中的關鍵技術。

3.1  修改函數調用指令

    編譯特殊需求:函數調用方式要求為間接地址調用。

    Gcc編譯C代碼生成的匯編文件中函數調用采用的是相對地址偏移跳轉方式。ARM匯編中,BL指令為函數調用指令,為實現函數調用方式改變,我們必須對所有BL指令進行修改。在匯編這個環節進行修改,而不是.o文件,因為.o文件修改可能會破壞相對地址跳轉類指令,例如B指令。

    例如:某段C代碼編譯產生的匯編文件中可能出現下面的函數調用語句

    bl    Fun_No1

    這種函數調用形式實際上是相對地址偏移跳轉,不滿足編譯模塊對函數調用方式的特殊需求,為了實現函數間接地址跳轉,對函數調用匯編語句進行修改模擬BL指令動作,修改后的匯編形式如下:

       b     .$L0
.$L1:
       .word      52
.$L0:
       ldr   r8,.$L1
       ldr   r8,[r8]
       mov lr,pc
       mov pc,r8

    .word      52為Fun_No1的函數指針地址,該地址需要進行重定位,此處重定位信息提取將在提取機器碼部分介紹。
 兩條ldr指令將指針指向地址取出,然后賦給pc實現函數間接地址調用。其中標號.$L0中使用符號$可以保證標號的唯一性,C語言中標示符中不可能出現$符號。

    說明: BL(Branch and Link)指令,該指令執行引起地址跳轉到一個目的地址,并且將函數返回地址存儲到LR寄存器中;LR寄存器,即Link Register(R14),該寄存器保存BL指令下一條指令的地址,函數從子例程返回后從該地址開始繼續執行;PC寄存器,即Program Counter,可以在大多數指令中做為一個指令指針,總是指向當前執行指令后的第二條指令。所有的ARM指令均四字節長。并且總是對齊到四字節邊界,所以PC中最低兩位總是0。[1]

3.2 提取重定位信息

    編譯特殊需求:搜集目標代碼中的重定位信息。

    編譯模塊生成的目標代碼下裝到控制器后需要重定位才能進行IEC運算,由于在鏈接后,Gcc在反編譯目標代碼已經無法提取重定位信息,所以要在鏈接前提取重定位信息。在連接的過程中,目標代碼的長度和執行順序都沒有變化,只是操作變量或指針的地址進行了重新填充,所以在連接前提取的重定位信息對鏈接后的代碼同樣適用。

    在鏈接前,通過調用Gcc工具鏈中的反編譯程序objdump,以-r作為命令行參數可得到當前代碼中需要進行重定位的位置信息。即以”objdump -r *.o -o *.r”為參數啟用新進程執行反編譯程序objdump,生成包含重定位信息的.r文件。整理.r文件中所有的重定位信息得到最終目標文件中的一部分重定位數據。另外一部分重定位信息在提取機器碼階段獲得,在后面內容中會介紹。下面舉例說明.r文件中的重定位信息:

    執行命令objdump –r Test.o結果如下:

Test.o:     file format elf32-bigarm
 
RELOCATION RECORDS FOR [.text]:
OFFSET        TYPE                    VALUE
00000030      R_ARM_ABS32    AT_VAR
00000064      R_ARM_PC24      .text
... ...

    說明:由于AutoThinker對應的控制器程序不支持代碼段重定位,只支持數據段的重定位,所以在提取重定位信息的時候,只需要提取數據段重定位數據。例子中TYPE為R_ARM_ABS32的行記錄了數據段重定位信息,該行中OFFSET項表明Test.o文件中代碼段偏移0x00000030處開始的四字節數據需要進行重定位處理。

3.3 鏈接

    編譯模塊特殊需求:實現變量指定地址分配。

    簡單的講,鏈接器的工作就是解析未定義的符號引用,將目標文件(這里指.o文件)中的占位符替換為符號的地址。目標文件是包括機器碼和鏈接器可用信息的程序模塊。鏈接器將完成程序中各目標文件的地址空間的組織。

    每個鏈接都被一個鏈接腳本所控制,這個腳本是用鏈接命令語言書寫的。

    鏈接腳本的一個主要目的是描述輸入文件中的節如何被映射到輸出文件中,并控制輸出文件的內存排布。幾乎所有的鏈接腳本只做這兩件事情。但是,在需要的時候, 鏈接腳本還可以指示鏈接器執行很多其他的操作。[2]

    鏈接器一般都有自己默認的鏈接腳本,要控制鏈接器的行為,可以過使用'-T'命令行選項來提供自己的鏈接腳本。

    使用'SECTIONS'命令來描述輸出文件的內存布局。下面內容摘自我們編寫的鏈接腳本myld.lds。

SECTIONS
{     
           . = 0x3008;
           .data : { *(.data) }
           MySection  0x00203008 : { *(MySection)}
              … …
. = 0x0100000;
           .text ALIGN(0x00100000) : { *(.text) }
}

    說明:腳本中命令指示,data段載入到地址0x3008處,text段載入到地址0x100000處,腳本中MySection為我們自己定義的段,對應于C代碼語句:

    AT_VAR_T  Var_Test  __attribute__((section("MySection")));[3]

    AT_VAR_T類型變量Var_Test將載入到地址0x00203008開始處。__attribute__為Gcc語法擴展。一般情況下編譯器將數據存放到data段或bss段中,當我們有特殊需求,需要將某些變量放到特定段中的時候可以使用Gcc__attribute__擴展語法。上面的C語句定義了新的段MySection,配合鏈接腳本myld.lds的定位功能我們就實現了變量的指定地址分配。

    執行鏈接操作的命令如下:

    ld –T myld.lds Test.o –o Test.l

    ld使用myld.lds作為鏈接腳本,將Test.o文件進行鏈接,生成文件Test.l。

3.4  提取機器碼

    編譯特殊需求:以函數為單位提取出編譯生成得二進制機器碼。

    借助Gcc工具鏈中的readelf工具,我們可以從鏈接后的.l文件中提取每個函數對應的二進制機器碼。

    執行命令readelf -S -s Test.l結果如下:

Section Headers:
  [Nr] Name         Type              Addr              Off         Size        ES   Flg Lk Inf Al
  … …
  [ 5] .text           PROGBITS    00100000       008000    000070    00  AX  0   0  4
  … …
 
Symbol table '.symtab' contains 22 entries:
   Num:    Value  Size   Type              Bind   Vis                  Ndx Name
       … …
    18:  00100044       0     NOTYPE  LOCAL  DEFAULT    8       .$L1
… …
    21: 0010005c         20    FUNC    GLOBAL     DEFAULT    5    main

    Section Headers部分第五行顯示.text段Addr屬性為0x00100000,該值與鏈接腳本中text段載入地址一致;.text段Off屬性為0x008000,該值表明Test.l中偏移0x8000處為text段內容。

    Symbol table部分第21行內容表示,main函數載入地址0x10005c,函數長度20。結合Section Header中獲得信息,我們可以知道Test.l文件中偏移0x805c(計算公式:函數載入地址-text段載入地址+text段在.l文件中的偏移。即,0x10005c - 0x100000 + 0x8000)處開始20個字節內容為main函數函數體對應的機器碼。

    Symbol Table部分第18行內容表示C代碼中標號$L1對應機器碼的載入地址為0x100044,結合Section Headers中信息,可以知道該標號相對text段的偏移為0x44,該標號指示位置需要進行重定位。此部分重定位信息與objdump提取的重定位信息相結合就得到了我們所需要的全部重定位信息。

4  結束語

    在嵌入式應用中,往往對編譯功能有種種的特殊需求。通過運用Gcc工具鏈中的各種編譯工具,我們可以定制程序編譯過程,以滿足特殊的編譯需求。

參考文獻

    [1]      ARM Limited.  ARM Architecture Reference Manual. June 2000.

    [2]      Free Software Foundation, Inc.ld.info. 2004.

    [3]      Richard M. Stallman and the GCC Developer Community.Using the GNU Compiler Collection. 2005.

熱點新聞

推薦產品

x
  • 在線反饋
1.我有以下需求:



2.詳細的需求:
姓名:
單位:
電話:
郵件:
主站蜘蛛池模板: 五月天婷婷激情,99久久精品久久久久久清纯,免费亚洲网站,久久精品亚洲乱码伦伦中文,精品久久久久久国产牛牛app,97不用下载 | 日韩精品免费观看,亚洲精品国产综合一线久久,99精品国产高清一区二区三区香蕉,亚洲图区欧美,日韩电影免费在线观看中文字幕,999国产精品999久久久久久 | 日韩精品电影在线观看-日韩精品电影在线-日韩精品电影一区-日韩精品电影-国产日韩欧美综合-国产日韩欧美在线一区二区三区 | 爆乳无码一区二区三区-爆乳熟妇一区二区三区霸乳-爆乳熟妇一区-爆乳少妇在办公室在线观看-爆乳护士一区二区三区在线播放-白丝一区二区三区 | 91香蕉导航-91香蕉成人免费高清网站-91香蕉成人-91午夜视频-91午夜精品亚洲一区二区三区-91网址在线观看 | 国产成人18黄网站免费网站-国产成人18黄网站免费-国产成人+亚洲欧洲-国产成年网站-国产成年-国产成a人亚洲精v品久久网 | 天天干天天操天天碰-天天干天天操天天摸-天天干天天操天天干-天天干天天操天天插-欧美一级久久久久久久久大-欧美一区二区VA毛片视频 | 久久就是精品-久久看片网-久久蝌蚪-久久老熟女一区二区三区-久久老司机波多野结衣-久久乐国产综合亚洲精品 | 国产一区二区三区四区五区加勒比-国产一区二区三区四区五区六区-国产一区二区三区四区五在线观看-国产一区二区三区无码A片-国产一区二区三区-国产一区二区三区亚洲欧美 | 中文字幕在线观看网址-中文字幕在线观看网站-中文字幕在线观看国产-中文字幕在线观看-开心片色99xxxx-开心久久激情 | 亚洲国产欧美精品-亚洲国产欧美国产综合一区-亚洲国产欧美国产第一区-亚洲国产模特在线播放-好吊色青青青国产在线播放-好吊色青青草 | 国产欧美日韩中文久久-国产欧美日韩在线一区二区不卡-国产欧美日韩在线人成aaaa-国产欧美日韩在线观看一区二区三区-婷婷国产天堂久久综合五月-婷婷99视频精品全部在线观看 | 99国产精品欧美久久久久久影院,日本不卡中文字幕,国产片在线观看播放,日韩国产欧美在线观看,久久综合狠狠综合久久97色,婷婷在线影院 | 国产视频自拍一区-国产手机精品一区二区-国产手机视频在线-国产手机视频在线观看-国产手机在线播放-国产手机在线观看精品视频 | 日操夜操天天操-午夜日日日日日日日日日-亚洲欧洲精品无视频一区二区三区四-国产成人精品无码-婷婷福利综合网-日逼影视 | 亚洲青草,日本成人a,欧美视频一区二区在线观看,国产精品porn,欧美国产精品va在线观看,精品一区二区三区的国产在线观看 | jizz.日本-jizz18高清视频-jizz18欧美-jizz18日本-欧美二区视频-欧美非洲黑人性xxxx | 国产首页-国产手机精品自拍视频-国产视频综合-国产视频自拍一区-香蕉网在线播放-香蕉网在线 | 久久99热不卡精品免费观看,色播综合,国产一级视频在线观看网站,激情综合激情,aa视频在线观看,五月天综合激情网 | 亚洲午夜久久久久中文字幕,欧美精品久久久久久久久大尺度,91精品推荐,九九久久99综合一区二区,哪里有毛片,精品亚洲一区二区三区 精品国产91乱码一区二区三区,成人国产一区二区三区精品,亚洲一区免费在线观看,日韩在线一区二区三区免费视频,波多野吉衣在线观看,日韩一级精品久久久久 | 波多野结衣在线中文-波多野结衣在线影视免费观看-波多野结衣在线影视-波多野结衣在线一区二区-波多野结衣在线一区-波多野结衣在线网址 | 国产三级在线观看视小说-国产三级在线观看视频不卡-国产三级在线观看视频-国产三级在线观看免费-西瓜视频网页版-西瓜视频全部免费观看大全 | 国产在线观看 完整版-国产在线高清不卡免费播放-国产在线不卡一区-国产在线不卡视频-亚洲国产精品影院-亚洲国产精品一区二区三区在线观看 | 国产视频自拍一区-国产手机精品一区二区-国产手机视频在线-国产手机视频在线观看-国产手机在线播放-国产手机在线观看精品视频 | 91香蕉视频在线播放-91香蕉视频在线看-91香蕉小视频-91香蕉亚洲精品人人影视-91香蕉影院-91香蕉在线视频 | 亚洲A片一区日韩精品无码-亚洲H成年动漫在线观看不卡-亚洲VA欧美VA天堂V国产综合-亚洲VA天堂VA欧美片A在线-亚洲爆乳精品无码AAA片-亚洲不卡高清免v无码屋 | 亚洲免费在线观看-做羞羞的事情的免费视频-最终痴汉电车在线观看-最新综艺-最新自拍偷拍-最新在线精品国自拍视频 | 精品欧美小视频在线观看-精品欧美18videosex欧美-精品免费在线视频-精品免费视在线视频观看-亚洲视频区-亚洲视频欧美在线专区 | 竹菊影视一区二区三区-竹菊一区二区-竹菊一区-重口味调教-另类小说h-另类小说 成 人 色综合 | 日本xxxxx18护士xxx-日本xxxxwwww-日本xxxx1819黑人-日本xxxbbb0oo-国产精品免费看久久久-国产精品免费久久久免费 | 在线看国产,精品国产一区二区二三区在线观看,国产一区二区三区视频,美女一级毛片免费观看,日韩aa在线观看,成人精品一区二区www | 欧美日韩在线成人免费-欧美日韩在线成人看片a-欧美日韩在线不卡-欧美日韩在线播放-自拍偷拍三级-自拍偷拍欧美亚洲 | 日韩在线黄色-日韩在线观看精品-日韩在线观-日韩在线高清视频-日韩在线不卡视频-日韩在线播放中文字幕 | 极品白丝-激性欧美激情在线播放16页-激情综合五月天丁香婷婷-激情伊人网-亚洲天堂久久精品成人-亚洲天堂久久精品 | 牛牛精品专区在线-牛牛超碰 国产-牛和人交videos欧美-妞干网手机免费视频-99精品视频在线观看免费-99精品视频在线观看re | 久久99热不卡精品免费观看,色播综合,国产一级视频在线观看网站,激情综合激情,aa视频在线观看,五月天综合激情网 | 日本b站一卡二不卡三卡四卡-日本a在线天堂-人与动性行为高清在线播放-人体自拍亚洲综合图区-avav456-avaiai114 | 婷婷综合激情五月中文字幕,美国性网站,国产精品亚洲欧美日韩久久,每日更新在线观看,久久免费视屏,www.成年人视频 | 99这里只有精品6-99这里只有精品-99在线在线视频免费视频观看-99在线小视频-97ai蜜桃小说及图片-97ai蜜桃图片区 | 在线亚洲不卡,三上悠亚一区二区观看,91伊人久久,婷婷激情五月,中文字幕久久精品,色综合久久中文字幕 | 美女内射毛片在线看-美女内射毛片在线看免费人动物-美女内射视频WWW网站午夜-美女强奷到抽搐在线播放-美女视频黄a视频全免费网站色窝-美女视频黄的全是免费 |