一、section
section 用于指定變量或函數存儲段,例如:
int *A __attribute__((section(".mysec"))) = &B;
就會把變量A放在.mysec段,可以放多個變量在同一個段,同一個段的變量在位址上是連續的。
不同編譯器、環境下對其方式不一樣,隻有對其機關是與儲存的指針資料長度一樣才可以確定兩個連續的section可以通過指針自加通路兩個段。
經典啟動初始化用法舉例:
#include <stdio.h>
//定義函數指針類型
typedef int(*ex_init)(void);
//導出指令
#define EXPORT(fn,level) __attribute__((used)) ex_init _init_##fn __attribute__((section(".My0."level))) = fn
//0段起始
int Start_0()
{
printf("Start_0\r\n");
return 0;
}
//導出
EXPORT(Start_0, "0");
//0段第一個函數
int Init_A01(void)
{
printf("A01\r\n");
return 0;
}
EXPORT(Init_A01, "0");
//0段第二個函數
int Init_A02(void)
{
printf("A02\r\n");
return 0;
}
EXPORT(Init_A02, "0");
//0段結束
int End_0()
{
printf("End_0\r\n");
return 0;
}
EXPORT(End_0, "0");
//1段起始
int Start_1(void)
{
printf("Start_1\r\n");
return 0;
}
EXPORT(Start_1, "1");
//1段第一個函數
int Init_A11()
{
printf("A11\r\n");
return 0;
}
EXPORT(Init_A11, "1");
//1段結束
int End_1()
{
printf("End_1\r\n");
return 0;
}
EXPORT(End_1, "1");
int main()
{
printf("**************Phase 1**************\r\n");
ex_init *ptr = &_init_Start_0;
for (; ptr <= &_init_End_0; ptr++)
{
(*ptr)();
}
printf("**************Phase 2**************\r\n");
ptr = &_init_Start_1;
for (; ptr <= &_init_End_1; ptr++)
{
(*ptr)();
}
/* 我的第一個 C 程式 */
getchar();
return 0;
}
運作main.c同一目錄下批處理腳本(我的gcc不能用,mgcc是自己重命名了一個exe程式,需要根據自己的gcc修改):
mgcc -c main.c
mgcc main.c
objdump -h main.o
a.exe
得到: