天天看點

C語言__attribute__學習記錄

一、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
           

得到:

C語言__attribute__學習記錄

繼續閱讀