How do I access a specific RAM location by address?

9

I'm starting to study pointers in C / C ++ and it was something that drew my attention to the robustness and range of possibilities. However, I can only access memory locations by assigning my pointer an address of an already allocated variable, as in:

#include <stdio.h>

void main(){
    int x =0, *p =&x;
    printf("%x",p); 

    return 0;
} 

And the address of my pointer (as well as the address of my variables), in this case, is chosen by the operating system Loader, I think.

I would like to allocate my variables in specific memory positions (chosen by me), and I would like, for example, to access the 0x000001 position of my RAM (Yes! I want to screw the Operating System). Is this possible using pointers? Is there any other way to do this? What and how?

    
asked by anonymous 13.03.2014 / 18:07

2 answers

10

To start, strictly speaking, you can only write and read data from valid pointers, that is, pointers created from objects within their lives. A pointer to any other place is invalid and can not be read or written, although it may exist (like NULL ). But, of course, you're talking about reality and practice, not what the perfect world should be like.

In any modern operating system there is something called virtual memory ( Virtual Memory ). In this way each process exists and works only with its limited view of memory. A process views memory as a large block of 16 exbibytes (I'm considering 64-bit) in which it has access to anywhere. With each address it tries to read, the system translates the address that the process sees to the address where the data actually is. So two different processes can read exactly the same address and receive different data.

This virtual memory is divided into pages (usually blocks of 4 kibibytes) and the system has a table that assigns virtual pages to actual pages. This is what allows the system, for example, to save an unused page on disk to free up memory and retrieve it as soon as the process tries to read its address, all transparently.

When you try to access an address that is not assigned in the virtual page table (or when you try to write to a read-only page, or run a non-executable, etc.) you will have a memory- . Your process will receive a SIGSEGV and will be finalized. A crash.

As much as you want, you will not be able to cause any damage to your system using just an ordinary process. You can not read kernel memory or read memory from other processes simply by using pointers like this. All you can do is read a page that does not exist and the process will die.

Now ... If you really want to cause problems then you have to make your code run as a little more than a process. How about a kernel module? In this case you are the system itself and uses real memory, you are in ring-0. In this situation you can read or write whatever you like. But note that trying to read an address out of memory, for example, will cause you a hardware exception. A nice blue screen or a kernel panic for you.

You can also by your code on a microcontroller or something similar, running without the existence of an operating system.

    
13.03.2014 / 18:38
6
As you have pointed out, you can not say explicitly where a variable will be stored in memory, because many things are done by the operating system in relation to memory itself (which results in the fact that virtual memory mapping is not a process.)

However, nothing prevents you from initializing a pointer with a specific memory address:

volatile unsigned int *ponteiro = (volatile unsigned int *)0x000001;
/* volatile está sendo usado com o intuito de garantir que o valor passado ao ponteiro não
   seja uma cópia previamente possuída pelo programa, ou seja, garante que seu valor está
   sendo obtido diretamente da memória em cada acesso. */
    
13.03.2014 / 18:47