Can we assign a value to this memory cell?

I want to assign some value (e.g. 2345) to a memory location (e.g. 0X12AED567). It can be done?

In other words, how can I implement the following function?

void AssignValToPointer(uint32_t pointer, int value) { } 
+7
source share
7 answers

The answer depends on some factors. Does your program work in a modern operating system?

If so, attempting to access a memory area that is not displayed will cause SIGSEGV . To do this, you need to use the system function to map the area of โ€‹โ€‹memory that contains this exact address before trying to access it.

+2
source

The fact that you are asking this question indicates that you are above your head. But here you go:

 *(int *)0x12AED567 = 2345; 
+12
source

As for C, this behavior is undefined. My next suggestion is undefined behavior, but avoids all problems based on types and aliases: use characters.

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

In addition, you can directly access bytes q[i] . (This is part of UB: the q pointer was not obtained as the address of the actual object or as a result of the allocation function. Sometimes this is normal, for example, if you write a stand-alone program that works in real mode and accesses the graphics hardware, you can write to graphics memory directly at the well-known hard-coded address.)

+2
source

Just treat the memory location as a pointer

 int* pMemory = OX12AED567; *pMemory = 2345; 

Note. This will only work if this memory location is accessible and writable by your program. Writing to an arbitrary memory location, as it is, is inherently dangerous.

+1
source

Standard Draft C99

This is probably not possible without the implementation of certain behaviors.

About methods like:

 *(uint32_t *)0x12AED567 = 2345; 

C99 N1256 standard design "6.3.2.3 Pointers" says:

5 An integer can be converted to any type of pointer. Except as noted above, the result is determined by the implementation, may not be aligned correctly, may not point to an object of a reference type, and may be a trap representation. 56)

GCC Implementation

GCC documents its int to implement the pointer at: https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Arrays-and-pointers-implementation.html#Arrays-and-pointers-implementation

Casting from an integer to a pointer discards the most significant bits, if the pointer representation is less than an integer type, propagates in accordance with the signature of the integer type, if the pointer representation is larger than the integer type, otherwise the bits do not change,

therefore, the cast will work as expected for this implementation. I expect other compilers to do similar things.

+1
source

Provided that it is not portable or safe (in general):

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

You indicated that the address is a physical address and that your code is running in the process.

So if you

  • in the form of a high-level operating system, for example. Linux, you need to get a mapping in the physical address space. On Linux, / dev / mem does this for you.

  • in the kernel or without an operating system and with an MMU, you must translate the physical address into a virtual address. In the Linux kernel, phys_to_virt () does this for you. I believe that in the kernel this address is always displayed.

  • in the kernel or without an operating system and without MMU you write directly to this address. There is no comparison to consider at all.

Now you have a valid mapping or the physical address itself, which you pass to your function.

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

You might want to add the volatile keyword, because the compiler can optimize the write operation if you do not read from this location after that (a likely case when writing to the memory register of the hardware register).

You can also use the uintptr_t data type instead of uint32_t for a pointer.

0
source

All Articles