我们可以为给定的内存位置分配值吗?

我想将一些值(比如2345)分配给一个内存位置(比如说0X12AED567)。 可以这样做吗?

换句话说,我该如何实现以下function?

void AssignValToPointer(uint32_t pointer, int value) { } 

答案取决于一些因素。 您的程序是否在现代操作系统中运行?

如果是,尝试访问未映射的内存区域将导致SIGSEGV 。 要实现这一点,您必须使用特定于系统的函数来映射包含此确切地址的内存区域,然后再尝试访问它。

你提出这个问题的事实表明你已经过了头脑。 但是你走了:

 *(int *)0x12AED567 = 2345; 

只需将内存位置视为指针即可

 int* pMemory = OX12AED567; *pMemory = 2345; 

注意:仅当程序可以访问和写入该内存位置时,此方法才有效。 写入这样的任意存储位置本质上是危险的。

就C而言,这是未定义的行为。 我的以下建议也是未定义的行为,但避免了所有基于类型和基于别名的问题:使用字符。

 int a = get_value(); char const * const p = (const char * const)&a; char * q = (char *)0x12345; memcpy(q, p, sizeof(int)); 

或者,您可以直接访问字节q[i] 。 (这是UB的一部分:指针q不是作为实际对象的地址获得的,也不是作为分配函数的结果。有时这是正常的;例如,如果你正在编写一个独立的程序,在实模式下运行并访问图形硬件,您可以直接在一个众所周知的硬编码地址写入图形内存。)

C99标准草案

没有实现定义的行为,这可能是不可能的。

关于演员:

 *(uint32_t *)0x12AED567 = 2345; 

C99 N1256标准草案 “6.3.2.3指针”说:

5整数可以转换为任何指针类型。 除非先前指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。 56)

GCC实施

GCC将其int指向以下的指针实现: https : //gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Arrays-and-pointers-implementation.html#Arrays-and-pointers-implementation

如果指针表示小于整数类型,则从整数到指针的强制转换丢弃最高有效位,如果指针表示大于整数类型,则根据整数类型的符号扩展,否则位不变。

所以演员阵容将按照预期的方式运作。 我希望其他编译器能做类似的事情。

附带条件是它不便携或安全(根本):

 *((int *)0x12AED567) = 2345; 

您已指出,该地址是一个物理地址,并且您的代码正在进程中运行。

所以,如果你是

  1. 在高级操作系统(例如Linux)中,您必须获得映射到物理地址空间。 在Linux中,/ dev / mem为您做到了这一点。

  2. 在内核中或没有操作系统和MMU的情况下,您必须将物理地址转换为虚拟地址。 在Linux内核中,phys_to_virt()为您做到了这一点。 在内核中,我假设,该地址始终被映射。

  3. 在内核中或没有操作系统且没有MMU的情况下,您可以直接写入该地址。 根本没有可以考虑的映射。

现在,您有一个有效的映射或物理地址本身,您传递给您的函数。

 void AssignValToPointer(uint32_t pointer, int value) { * ((volatile int *) pointer) = value; } 

您可能希望添加volatile关键字,因为如果您之后没有从该位置读取(可能是写入内存映射硬件的寄存器的情况),编译器可能会优化写操作。

您可能还希望使用uintptr_t数据类型而不是uint32_t作为指针。