国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言開發中可能會用到的GNU

Q4MP_gh_c472c21 ? 來源:開源博客 ? 作者:-_-struggle ? 2021-11-17 10:41 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

為了方便使用,GNU C在標準C語言的基礎上進行了部分方便開發的擴展。

這里講解一些開發中可能會用到的,或者使用頻率比較高的內容。

零長度數組和變量長度數組

GNU C 允許使用零長度數組,比如:

char data[0];

GNU C 允許使用一個變量定義數組的長度如:

int n=0;
scanf("%d",&n);
int array[n];

case 范圍

GNU C支持 case x...y這樣的語法,[x,y]之間數均滿足條件。

case 'a'...'z':  /*from 'a' to 'z'*/
break;

語句表達式


GNU C 把包含在括號中的復合語句看作是一個表達式,稱為語句表達式。

 #define min_t(type,x,y)
         ({type __x=(x); type __y=(y);__x<__y?__x:__y;})

這種寫法可以避免:

 #define min_t(x,y) ((x)<(y)?(x):(y))

在min_t(x++,++y)中出現的副作用。

typeof 關鍵字

typeof(x)可以獲得x的類型借助typeof關鍵字我們可以重新定義min_t:

#define min_t(x,y)
    ({typeof(x) __x=(x); typeof(y) __y=(y);__x<__y?__x:__y;})

可變參數宏

GNU C中宏也支持可變參數:

#define pr_debug(fmt,arg...) 
        printk(fmt,##arg)

這里,如果可變參數被忽略或為空,“##”操作將使預處理器去掉它前面的那個逗號。如果你在宏調用時,確實提供了一些可變參數,GNU C也會工作正常,它會把這些可變參數放到逗號的后面。

標號元素

標準C要求數組或結構體的初始化值必須以固定的順序出現,在GNU C中,通過指定索引或結構體成員名,允許初始化以任意順序出現。

unsigned char data[MAX] =
{
         [0]=10,
         [10]=100,
};


struct file_operations ext2_file_operations=
{
        open:ext2_open,
        close:ext2_close,
};

linux 2.6中推薦如下方式:

struct file_operations ext2_file_operations=
{
     .read=ext2_read,
     .write=ext2_write,
};

當前函數名

GNU C中預定義兩個標志符保存當前函數的名字,__ FUNCTION __ 保存函數在源碼中的名字, __ PRETTY__ FUNCTION __保存帶語言特色的名字。在C函數中這兩個名字是相同的。

void func_example()
{
     printf("the function name is %s",__FUNCTION__);
}

在C99中支持__ func __ 宏,因此建議使用 __ func __ 替代 __ FUNCTION __ 。

特殊屬性聲明

GNU C 允許聲明函數、變量和類型的特殊屬性,以便進行手工的代碼優化和定制。如果要指定一個屬性聲明,只需要在聲明后添加__ attribute __((ATTRIBUTE))。其中ATTRIBUTE為屬性說明,如果存在多個屬性,則以逗號分隔。GNU C 支持noreturn,noinline, always_inline, pure, const, nothrow, format, format_arg, no_instrument_function, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias warn_unused_result nonnull等十個屬性。

noreturn屬性作用于函數,表示該函數從不返回。這會讓編譯器優化代碼并消除不必要的警告信息。例如:

#define ATTRIB_NORET __attribute__((noreturn)) ....
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;

packed屬性作用于變量和類型,用于變量或結構域時,表示使用最小可能的對齊,用于枚舉、結構或聯合類型時表示該類型使用最小的內存。如對于結構體,就是它告訴編譯器取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊。例如:

struct example_struct
{
         char a;
         int b;
         long c;
} __attribute__((packed));

regparm屬性用于指定最多可以使用n個寄存器(eax, edx, ecx)傳遞參數,n的范圍是0~3,超過n時則將參數壓入棧中(n=0表示不用寄存器傳遞參數)。

注意:以上這些屬性都是在X86處理器體系結構下的,在X64體系結構下,大部分內容都是同樣有效的。但是,這里要注意regparm屬性,由于在X64體系結構下,GUN C的默認調用約定使用寄存器傳遞參數。所以,如果regparm屬性里使用的寄存器個數超過3個,也仍然會使用其他寄存器來傳遞參數。這一點要遵循X64體系結構的調用約定。

下面可以看一個例子:

int q = 0x5a;
int t1 = 1;
int t2 = 2;
int t3 = 3;
int t4 = 4;
#define REGPARM3 __attribute((regparm(3)))
#define REGPARM0 __attribute((regparm(0)))
void REGPARM0 p1(int a)
{
     q = a + 1;
}


void REGPARM3 p2(int a, int b, int c, int d)
{
     q = a + b + c + d + 1;
}


int main()
{
    p1(t1);
    p2(t1,t2,t3,t4);
    return 0;
}

使用objdump命令反匯編,相關命令如下:

objdump -D 可執行程序

其中-D選項用于反匯編所有的程序段,包括:代碼段、數據段、只讀數據段以及一些系統段等等。而-d命令只反匯編代碼段的內容。

反匯編后的關鍵代碼如下:

Disassembly of section .text:
0000000000400474 :
  400474:    55                       push   %rbp
  400475:    48 89 e5                 mov    %rsp,%rbp
  400478:    89 7d fc                 mov    %edi,-0x4(%rbp)
  40047b:    8b 45 fc                 mov    -0x4(%rbp),%eax
  40047e:    83 c0 01                 add    $0x1,%eax
  400481:    89 05 3d 04 20 00        mov    %eax,0x20043d(%rip)        # 6008c4 
  400487:    c9                       leaveq 
  400488:    c3                       retq   


0000000000400489 :
  400489:    55                       push   %rbp
  40048a:    48 89 e5                 mov    %rsp,%rbp
  40048d:    89 7d fc                 mov    %edi,-0x4(%rbp)
  400490:    89 75 f8                 mov    %esi,-0x8(%rbp)
  400493:    89 55 f4                 mov    %edx,-0xc(%rbp)
  400496:    89 4d f0                 mov    %ecx,-0x10(%rbp)
  400499:    8b 45 f8                 mov    -0x8(%rbp),%eax
  40049c:    8b 55 fc                 mov    -0x4(%rbp),%edx
  40049f:    8d 04 02                 lea    (%rdx,%rax,1),%eax
  4004a2:    03 45 f4                 add    -0xc(%rbp),%eax
  4004a5:    03 45 f0                 add    -0x10(%rbp),%eax
  4004a8:    83 c0 01                 add    $0x1,%eax
  4004ab:    89 05 13 04 20 00        mov    %eax,0x200413(%rip)        # 6008c4 
  4004b1:    c9                       leaveq 
  4004b2:    c3                       retq   


00000000004004b3 
: 4004b3: 55 push %rbp 4004b4: 48 89 e5 mov %rsp,%rbp 4004b7: 53 push %rbx 4004b8: 8b 05 0a 04 20 00 mov 0x20040a(%rip),%eax # 6008c8 4004be: 89 c7 mov %eax,%edi 4004c0: e8 af ff ff ff callq 400474 4004c5: 8b 0d 09 04 20 00 mov 0x200409(%rip),%ecx # 6008d4 4004cb: 8b 15 ff 03 20 00 mov 0x2003ff(%rip),%edx # 6008d0 4004d1: 8b 1d f5 03 20 00 mov 0x2003f5(%rip),%ebx # 6008cc 4004d7: 8b 05 eb 03 20 00 mov 0x2003eb(%rip),%eax # 6008c8 4004dd: 89 de mov %ebx,%esi 4004df: 89 c7 mov %eax,%edi 4004e1: e8 a3 ff ff ff callq 400489 4004e6: b8 00 00 00 00 mov $0x0,%eax 4004eb: 5b pop %rbx 4004ec: c9 leaveq 4004ed: c3 retq 4004ee: 90 nop 4004ef: 90 nop Disassembly of section .data: 00000000006008c0 <__data_start>: 6008c0: 00 00 add %al,(%rax) ... 00000000006008c4 : 6008c4: 5a pop %rdx 6008c5: 00 00 add %al,(%rax) ... 00000000006008c8 : 6008c8: 01 00 add %eax,(%rax) ... 00000000006008cc : 6008cc: 02 00 add (%rax),%al ... 00000000006008d0 : 6008d0: 03 00 add (%rax),%eax ... 00000000006008d4 : 6008d4: 04 00 add $0x0,%al ...

如果讀者還記得2.2.3節中,關于GCC基于X64體系結構的調用約定的話,那就很容易可以看出,函數p1和p2都使用寄存器傳遞參數,順序就是RDI, RSI, RDX, RCX,這些細節已經跟regparm的規定完全不一致了。所以,在這里作者覺得,regparm已經不起作用了。

來源:https://my.oschina.net/LinuxDaxingxing/blog/751319
責任編輯:haq
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    183

    文章

    7642

    瀏覽量

    144766
  • GNU
    GNU
    +關注

    關注

    0

    文章

    144

    瀏覽量

    18248

原文標題:你知道GNU C對C語言的擴展嗎?

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    C語言單元測試在嵌入式軟件開發的作用及專業工具的應用

    一、C語言在嵌入式開發的現狀與重要性 C語言在嵌入式開發
    發表于 12-18 11:46

    單片機開發功能安全編譯器

    ”的代碼路徑。高級語言,特別是CC ++,包含數量眾多的功能,這些功能的行為不是代碼所遵循的語言規范所規定的。這種不確定的行為可能導致意外
    發表于 12-01 06:44

    哪些場合會用到volatile關鍵字?

    當你理解 volatile關鍵字的含義之后,你就能明白,其實很多場合都能用到 volatile關鍵字。 1.全局變量單片機開發,難免會用到全局變量。一些初級工程師,更是全局變量滿天飛。這種情況下
    發表于 11-25 08:19

    C語言特性

    1、高效性:直接操作硬件 C 語言代碼的執行效率極高,這是其最為顯著的優勢之一。它能夠直接訪問硬件資源,與底層硬件進行緊密交互,充分發揮硬件的性能潛力。在嵌入式開發,硬件資源往往十分
    發表于 11-24 07:01

    C語言在嵌入式開發的應用

    1、控制系統開發 在工業控制領域,C 語言是當之無愧的中流砥柱。無論是工業自動化生產線的運動控制、溫度控制、壓力控制等系統,還是汽車電子
    發表于 11-21 08:09

    哪些電子產品會用到貼片Y電容?

    貼片Y電容,又稱為表面貼裝Y電容,外觀通常為扁平的矩形,是一種特殊的電容器類型。由于其獨特的性能優勢用于許多電子產品。哪些電子產品會用到貼片Y電容呢?
    的頭像 發表于 11-13 11:05 ?307次閱讀
    哪些電子產品<b class='flag-5'>會用到</b>貼片Y電容?

    【HZ-T536開發板免費體驗】2 - 交叉編譯倉頡編程語言程序到開發板運行

    AARCH64的編譯器(我使用的是WSL2): sudo apt install gcc-aarch64-linux-gnu 然后需要拷貝aarch64開發以下三個目錄的文件到x86_64的Linux軟件包
    發表于 07-16 21:27

    工業物聯網網關會用到哪些電子模組

    工業物聯網網關通常會用到通信模組、主控模組、安全模組、接口擴展模組和電源管理模組等,以下是具體介紹: 通信模組:用于實現網關與外部網絡或設備的通信連接。常見的有5G/4G模組,如華為MH5000、移
    的頭像 發表于 07-11 17:56 ?780次閱讀

    工業RTU會用到哪些芯片

    工業RTU(遠程終端單元)通常會用到處理器芯片、通信芯片、數據采集芯片、存儲芯片和電源管理芯片等。
    的頭像 發表于 07-05 09:15 ?590次閱讀

    工業網關會用到哪些芯片

    工業網關通常會集成多種芯片以滿足其復雜的功能需求,具體可能會用到以下幾類芯片: 處理器芯片:這是工業網關的核心部件,負責執行控制指令、數據處理以及運行操作系統等任務。可能會采用高性能的ARM架構
    的頭像 發表于 07-03 17:26 ?558次閱讀

    提高篇——C語言核心技術(中文版)

    嚴謹的術語表介紹C語言;第二部分描述標準鏈接庫;第三部分介紹GNU軟件包中常用的編譯和測試工具。 獲取完整文檔資料可下載附件哦!!!!如果內容有幫助可以關注、點贊、評論支持一下哦~
    發表于 06-13 16:39

    HTTP協議在工業領域會用到

    HTTP協議在工業領域會用到,并且在工業互聯網、設備管理、數據交互等多個方面發揮著重要作用,以下為你詳細介紹: 工業互聯網場景 設備接入與管理 原理:在工業互聯網平臺中,各類工業設備(如傳感器
    的頭像 發表于 06-03 09:17 ?539次閱讀

    深入理解C語言C語言循環控制

    C語言編程,循環結構是至關重要的,它可以讓程序重復執行特定的代碼塊,從而提高編程效率。然而,為了避免程序進入無限循環,C語言提供了多種循
    的頭像 發表于 04-29 18:49 ?1771次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>C</b><b class='flag-5'>語言</b>循環控制

    S32G2如何利用C語言開發IPCF?

    S32G2 應該如何利用 C語言在 A 核上開發 IPCF 程序,是否有相關的 SDK 可用?或者我需要將 ipc-shm 等封裝到一個 C
    發表于 03-27 06:49

    分析C語言代碼結構的設計問題

    來分析一個C語言代碼結構的設計問題。 這段代碼,使用了兩次malloc,分別給 p1 和 p2 申請了內存。用完后,內存釋放,防止內存泄漏。 大家覺得,這樣的代碼設計有沒有問題。 代碼是某位學員在
    的頭像 發表于 02-11 09:31 ?706次閱讀