I'm trying to access a certain location in memory and retrieve the contents of that memory location but the program seems to not work when I run it. I don't get any errors it's just a blank console screen. The first thing that came to my mind is that it would probably be a security breach to be able to access a memory location like this. Is that the reason or is my code wrong?
int main()
{
int * pointer = 100;
printf("%d", *pointer);
return 0;
}
Memory mapped registers are an integral part of embedded programming - but you need to know where in memory to prod - random locations are likely to generate random effects (due to undefined behaviour)!
For embedded compilers, usually there is a header file full of lines similar to:
#define GPIO_PORTF_DIR_R (*( ( volatile unsigned int * )0x40025400 ) )
These (a) map registers appropriately and (b) hide the specific implementation.
Note the use of the volatile qualifier - any memory mapped access should be volatile qualified, otherwise there is scope for compiler optimisation to have an effect too!
Now we can use this name inside your code to read and write to that register (wherever it happens to be):
GPIO_PORTF_DIR_R = 0xF0;
data = GPIO_PORTF_DIR_R;
The fact that your code results in "just a blank console screen" means it's not doing what you expect... your random location is causing random (undefined) behaviour.
Related
I know that the global variable is stored in memory, and the local variable is saved in the stack, and the stack will be destroyed after each use.
But I do not know how an array is saved in memory.
I tried to declare a global array:
int tab[5]={10,9,12,34,30};
and at the end I read the contents of the memory, I mean, that after the execution of the code, I read the contents of the memory, (e.g I'm working on a microcontroller, and I know where the data is saving) when I declare a global variable for example a = 10; and when I read the contents of the memory I find the value 10 in the memory, but I do not find the content of the table that is 10,9,12,34,30
I want to understand where the array content is it save in memory?
I work on Aurix Infineon, and I use Hightec as a compiler, I execute my code directly on the aurix, I read the memorition like this:
const volatile unsigned char * mem_start = 0xd0000000;
#define size ((ptrdiff_t) 0xfff)
unsigned char bufferf [size];
code ();
main(){
...
for (int e = 0; e < sizeof (bufferf); e ++)
bufferf [e] = * (mem_start + e); // read memory
}
The answer to the question of where arrays, or indeed any variables, are stored depends on whether you are considering the abstract machine or the real hardware. The C standard specifies how things work on the abstract machine, but a conforming compiler is free to do something else on the real hardware (e.g., due to optimization) if the observable effects are the same.
(On the abstract machine, arrays are generally stored in the same place as other variables declared in the same scope would be.)
For example, a variable might be placed in a register instead of the stack, or it might be optimized away completely. As a programmer you generally shouldn't care about this, since you can also just consider the abstract machine. (Admittedly there may be some cases where you do care about it, and on microcontrollers with very limited RAM one reason might be that you have to be very frugal about using the stack, etc.)
As for your code for reading the memory: it cannot possibly work. If size is the size of the memory available to variables, you cannot fit the array bufferf[size] in that memory together with everything else.
Fortunately, copying the contents of the memory to a separate buffer is not needed. Consider your line bufferf[e] = *(mem_start + e) – since you can already read an arbitrary index e from memory at mem_start, you can use *(mem_start + e) (or, better, mem_start[e], which is exactly equivalent) directly everywhere you would use bufferf[e]! Just treat mem_start as pointing to the first element of an array of size bytes.
Also note that if you are programmatically searching for the contents of the array tab, its elements are ints, so they are more than one byte each – you won't simply find five adjacent bytes with those values.
(Then again, you can also just take the address of tab[0] and find out where it is stored, i.e., ((unsigned char *) tab) - mem_start is the index of tab in mem_start. However, here observing it may change things due to the aforementioned optimization.)
global variable is stored in memory, and the local variable is saved in the stack
This is false.
Global variables are sometimes kept in registers, not only in static memory.
If the function is recursive the compiler may choose to use the stack or not. If the function is tail recursive it is no need to use the stack as there is no continuation after the function returns and one can use the current frame for the next call.
There are mechanical methods to convert the code in continuation passing style and in this equivalent form it is evaluated stackless.
There are lots of mathematical models of computation and not all use the stack. The code can be converted from one model to other keeping the same result after evaluation.
You got these informations from books written in the 70s, 80s and in the meantime the process of evaluation of code was much improved (using methods that were theoretical in the 30s but nowadays are implemented in systems).
This program may get you closer to what you want:
int tab[] = {10, 9, 12, 34, 30};
// Used to get the number of elements in an array
#define ARRAY_SIZE(array) \
(sizeof(array) / sizeof(array[0]))
// Used to suppress compiler warnings about unused variables
#define UNUSED(x) \
(void)(x)
int main(void) {
int *tab_ptr;
int tab_copy[ARRAY_SIZE(tab)];
tab_ptr = tab;
UNUSED(tab_ptr);
for (int index = 0; index < ARRAY_SIZE(tab_copy); index++) {
tab_copy[index] = tab[index];
}
return 0;
}
I don't have the Hightec environment to test this, nor do I have an Aurix to run it on. However, this may give you a starting point that helps you obtain the information you desire.
It looks like the Infineon Aurix is a 32-bit little-endian machine. This means that an int will be 32-bits wide and the first byte will store the first 8 bits of the value. For example, the value 10 would be stored like this:
0a 00 00 00
If you try to read this memory as char, you will get 0x0a, 0x00, 0x00, and 0x00.
There is a constant global variable defined in another module.
I would like to manipulate this variable during run time (as I can't change in the other module and remove the const keyword).
I know that constants are put in ROM ...
The code will be downloaded to a micro controller (leopard powerpc 5643) , so I think that constants will be in the Flash Memory (not the normal PC ROM)
I have tried something like this and the compiler produced an error during compilation:
const int global_Variable = 0;
const int* ptr = &global_Variable;
*ptr = 5;
So , do you know any other way to accomplish this ?
If you know that the constant really is put into ROM (or, more likely, flash) on your platform, then of course you won't be able to modify it, at least not directly.
If it's flash, you might, but you're going to have to dive a bit deeper since reprogramming flash memory is not done by just writing to it, you must erase the relevant portion and there are often block/sector size limitations to deal with. It won't be pretty.
Your actual code fails to compile since you can't write through a const pointer (that's the point of the const, after all). You can cast away that and force the compiler to generate the write, but of course it won't work if the target address points to non-writable memory:
const int global_Variable = 0;
int *ptr = (int *) &global_Variable; /* Cast away the const. */
*ptr = 5; /* Do the write! */
Again, this won't work if global_Variable is in non-writable memory. You will get undefined results.
Lastly, which is so obvious that I didn't even think to write it: what you're doing sounds lika a very bad idea. Obviously the software you're working on was designed with the assumption that global_Variable be constant. You're trying to overthrow that particular part of the design, which very likely will break lots of things if you succeed. In other words: consider not doing this.
If you manage to place global_variable in a memory region that is writeable, here is a way to change its value. Notice that this won't work if global_variable is not physically writeable, e.g. because it sits in the ROM area.
int *ptr = (int*)&global_variable; /* the compiler will warn you about this */
*ptr = 5;
Notice that you might run into other problems down the road as the compiler might assume that the content of a variable declared as const does not change during the runtime of the program. You violate this assertion by altering the variable's value, so expect strange results.
What is wrong with the following code:
unsigned int *ptr;
ptr=(unsigned int*)0x1234;
*ptr=10;
/*do someting*/
*ptr=100;
Imp point, I have read the memory map of the microcontroller, and this location can be very much used by the programmer, so the case of not-owning-the-memory is ruled out.
All I want to find out is, can I use the above method to directly access a memory location?
Thanks in advance.
Yes it is fine, unless (as you said) you are within accessible memory range.
Also I would like to add, since you mentioned microcontroller, if this is address of a SFR or a GPR then its alias (using #define)must already be defined in the header for the controller, so it is better you use that alias, for improved readability/understandability and portability.
EDIT : (As Vlad pointed out in the comment)
Using volatile will make your program more safe & reliable, as compiler will not optimize out immediate memory write, and you can be sure that the value you write is immediately written to the location you want.
Yes you can use it, but be aware of the alignment issues. Depending in your microcontroller following might happen:
uint16_t * p1 = (uint16_t *)0x8;
uint16_t * p2 = (uint16_t *)0x9;
*p1 = 1; // Ok
*p2 = 1; // Unaligned access -> Crash or something else
ARM for example requires that 16-bit variables are aligned on even addresses (divisible by 2).
This question already has answers here:
Why is volatile needed in C?
(18 answers)
Closed 9 years ago.
I am writing program for ARM with Linux environment. its not a low level program, say app level
Can you clarify me what is the difference between,
int iData;
vs
volatile int iData;
Does it have hardware specific impact ?
Basically, volatile tells the compiler "the value here might be changed by something external to this program".
It's useful when you're (for instance) dealing with hardware registers, that often change "on their own", or when passing data to/from interrupts.
The point is that it tells the compiler that each access of the variable in the C code must generate a "real" access to the relevant address, it can't be buffered or held in a register since then you wouldn't "see" changes done by external parties.
For regular application-level code, volatile should never be needed unless (of course) you're interacting with something a lot lower-level.
The volatile keyword specifies that variable can be modified at any moment not by a program.
If we are talking about embedded, then it can be e.g. hardware state register. The value that it contains may be modified by the hardware at any unpredictable moment.
That is why, from the compiler point of view that means that compiler is forbidden to apply optimizations on this variable, as any kind of assumption is wrong and can cause unpredictable result on the program execution.
By making a variable volatile, every time you access the variable, you force the CPU to fetch it from memory rather than from a cache. This is helpful in multithreaded programs where many threads could reuse the value of a variable in a cache. To prevent such reuse ( in multithreaded program) volatile keyword is used. This ensures that any read or write to an volatile variable is stable (not cached)
Generally speaking, the volatile keyword is intended to prevent the compiler from applying any optimizations on the code that assume values of variables cannot change "on their own."
(from Wikipedia)
Now, what does this mean?
If you have a variable that could have its contents changed at any time, usually due to another thread acting on it while you are possibly referencing this variable in a main thread, then you may wish to mark it as volatile. This is because typically a variable's contents can be "depended on" with certainty for the scope and nature of the context in which the variable is used. But if code outside your scope or thread is also affecting the variable, your program needs to know to expect this and query the variable's true contents whenever necessary, more than the normal.
This is a simplification of what is going on, of course, but I doubt you will need to use volatile in most programming tasks.
In the following example, global_data is not explicitly modified. so when the optimization is done, compiler thinks that, it is not going to modified anyway. so it assigns global_data with 0. And uses 0, whereever global_data is used.
But actually global_data updated through some other process/method(say through ptrace ). by using volatile you can force it to read always from memory. so you can get updated result.
#include <stdio.h>
volatile int global_data = 0;
int main()
{
FILE *fp = NULL;
int data = 0;
printf("\n Address of global_data:%x \n", &global_data);
while(1)
{
if(global_data == 0)
{
continue;
}
else if(global_data == 2)
{
;
break;
}
}
return 0;
}
volatile keyword can be used,
when the object is a memory mapped io port.
An 8 bit memory mapped io port at physical address 0x15 can be declared as
char const ptr = (char *) 0x15;
Suppose that we want to change the value at that port at periodic intervals.
*ptr = 0 ;
while(*ptr){
*ptr = 4;//Setting a value
*ptr = 0; // Clearing after setting
}
It may get optimized as
*ptr = 0 ;
while(0){
}
Volatile supress the compiler optimization and compiler assumes that tha value can
be changed at any time even if no explicit code modify it.
Volatile char *const ptr = (volatile char * )0x15;
Used when the object is a modified by ISR.
Sometimes ISR may change tha values used in the mainline codes
static int num;
void interrupt(void){
++num;
}
int main(){
int val;
val = num;
while(val != num)
val = num;
return val;
}
Here the compiler do some optimizations to the while statement.ie the compiler
produce the code it such a way that the value of num will always read form the cpu
registers instead of reading from the memory.The while statement will always be
false.But in actual scenario the valu of num may get changed in the ISR and it will
reflect in the memory.So if the variable is declared as volatile the compiler will know
that the value should always read from the memory
volatile means that variables value could be change any time by any external source. in GCC if we dont use volatile than it optimize the code which is sometimes gives unwanted behavior.
For example if we try to get real time from an external real time clock and if we don't use volatile there then what compiler do is it will always display the value which is stored in cpu register so it will not work the way we want. if we use volatile keyword there then every time it will read from the real time clock so it will serve our purpose....
But as u said you are not dealing with any low level hardware programming then i don't think you need to use volatile anywhere
thanks
Is it possible to assign a variable the address you want, in the memory?
I tried to do so but I am getting an error as "Lvalue required as left operand of assignment".
int main() {
int i = 10;
&i = 7200;
printf("i=%d address=%u", i, &i);
}
What is wrong with my approach?
Is there any way in C in which we can assign an address we want, to a variable?
Not directly.
You can do this though : int* i = 7200;
.. and then use i (ie. *i = 10) but you will most likely get a crash. This is only meaningful when doing low level development - device drivers, etc... with known memory addreses.
Assuming you are on an x86-type processer on a modern operating system, it is not possible to write to aribtray memory locations; the CPU works in concert with the OS to protect memory so that one process cannot accidentally (or intentionally) overwrite another processes' memory. Allowing this would be a security risk (see: buffer overflow). If you try to anyway, you get the 'Segmentation fault' error as the OS/CPU prevents you from doing this.
For technical details on this, you want to start with 1, 2, and 3.
Instead, you ask the OS to give you a memory location you can write to, using malloc. In this case, the OS kernel (which is generally the only process that is allowed to write to arbitrary memory locations) finds a free area of memory and allocates it to your process. The allocation process also marks that area of memory as belonging to your process, so that you can read it and write it.
However, a different OS/processor architecture/configuration could allow you to write to an arbitrary location. In that case, this code would work:
#include <stdio.h>
void main() {
int *ptr;
ptr = (int*)7000;
*ptr = 10;
printf("Value: %i", *ptr);
}
C language provides you with no means for "attaching" a name to a specific memory address. I.e. you cannot tell the language that a specific variable name is supposed to refer to a lvalue located at a specific address. So, the answer to your question, as stated, is "no". End of story.
Moreover, formally speaking, there's no alternative portable way to work with specific numerical addresses in C. The language itself defines no features that would help you do that.
However, a specific implementation might provide you with means to access specific addresses. In a typical implementation, converting an integral value Ato a pointer type creates a pointer that points to address A. By dereferencing such pointer you can access that memory location.
Not portably. But some compilers (usually for the embedded world) have extensions to do it.
For example on IAR compiler (here for MSP430), you can do this:
static const char version[] # 0x1000 = "v1.0";
This will put object version at memory address 0x1000.
You can do in the windows system with mingw64 setup in visual studio code tool, here is my code
#include<stdio.h>
int main()
{
int *c;
c = (int *)0x000000000061fe14; // Allocating the address 8-bit with respect to your CPU arch.
*c = NULL; // Initializing the null pointer for allocated address
*c = 0x10; // Assign a hex value (you can assign integer also without '0x')
printf("%p\n",c); // Prints the address of the c pointer variable
printf("%x\n",*c); // Prints the assigned value 0x10 -hex
}
It is tested with mentioned environment. Hope this helps Happy coding !!!
No.
Even if you could, 7200 is not a pointer (memory address), it's an int, so that wouldn't work anyway.
There's probably no way to determine which address a variable will have. But as a last hope for you, there is something called "pointer", so you can modify a value on address 7200 (although this address will probably be inaccessible):
int *i = (int *)7200;
*i = 10;
Use ldscript/linker command file. This will however, assign at link time, not run time.
Linker command file syntax depends largely on specific compiler. So you will need to google for linker command file, for your compiler.
Approximate pseudo syntax would be somewhat like this:
In linker command file:
.section start=0x1000 lenth=0x100 myVariables
In C file:
#pragma section myVariables
int myVar=10;
It's not possible, maybe possible with compiler extensions. You could however access memory at an address you want (if the address is accessible to your process):
int addr = 7200;
*((int*)addr) = newVal;
I think '&' in &a evaluates the address of i at the compile time which i think is a virtual address .So it is not a Lvalue according to your compiler. Use pointer instead