RealView ARM C编译器支座使用变量属性at(address)将变量放置在给定的内存地址
int var __attribute__((at(0x40001000)));
var = 4; // changes the memory located at 0x40001000GCC有相似的变量属性吗?
发布于 2010-11-01 09:40:33
我不知道,但您可以轻松地创建这样的解决方案:
int *var = (int*)0x40001000;
*var = 4;这不是完全相同的事情,但在大多数情况下,一个完美的替代品。它将适用于任何编译器,而不仅仅是GCC。
如果您使用GCC,我假设您也使用GNU ld (当然,这不是必然的),ld支持放置变量不管你想要什么。
我想让链接器做那个工作是很常见的。
受@肋骨的启发,我将补充如下:如果绝对地址是某个控制寄存器的地址,我会将volatile添加到指针定义中。如果它只是RAM,那就无关紧要了。
发布于 2010-11-02 19:54:05
您可以使用区段属性和ld 链接器脚本为该节定义所需的地址。这可能比你的选择更麻烦,但这是一个选择。
发布于 2019-01-10 12:21:15
最小可运行链接器脚本示例
在:https://stackoverflow.com/a/4081574/895245中提到了该技术,但现在我将提供一个具体的示例。
main.c
#include <stdio.h>
int myvar __attribute__((section(".mySection"))) = 0x9ABCDEF0;
int main(void) {
printf("adr %p\n", (void*)&myvar);
printf("val 0x%x\n", myvar);
myvar = 0;
printf("val 0x%x\n", myvar);
return 0;
}link.ld
SECTIONS
{
.mySegment 0x12345678 : {KEEP(*(.mySection))}
}编译和运行:
gcc -fno-pie -no-pie -o main.out -std=c99 -Wall -Wextra -pedantic link.ld main.c
./main.out输出:
adr 0x12345678
val 0x9abcdef0
val 0x0所以我们看到它被放在了想要的地址上。
我在GCC手册中找不到这一点,但有以下语法:
gcc link.ld main.c似乎将给定的链接器脚本附加到要使用的默认链接器脚本中。
-fno-pie -no-pie是必需的,因为Ubuntu现在被配置为默认生成饼式可执行文件,这导致Linux内核每次将可执行文件放置在不同的地址上,这会扰乱我们的实验。另见:gcc和ld中的位置独立可执行文件的-fPIE选项是什么?
TODO:编译会产生一个警告:
/usr/bin/x86_64-linux-gnu-ld: warning: link.ld contains output sections; did you forget -T?我做错了什么吗?怎么摆脱它?另见:如何删除警告: link.res包含输出部分;您忘记-T了吗?
在Ubuntu 18.10,GCC 8.2.0上测试。
https://stackoverflow.com/questions/4067811
复制相似问题