访问C中的特定内存位置

在汇编语言中,我们有类似的说明

Movl AX, [1000] 

这允许我们访问特定的内存位置。

但是在C中我们能做类似的事吗?

当然我知道使用asm()的内联汇编代码将允许你这样做。

但我想了解一些C特定技术来实现这一目标。

我尝试了以下代码并得到了分段错误

 int *ptr=0xFE1DB124; 

由于下面给出的代码识别出内存位置,这再次令人困惑,

 int var; printf("\nThe Address is %x",&var); 

所以内存位置可用,但我仍然得到分段错误。

常见的C编译器允许您设置一个整数的指针,并使用它来访问内存,它们将为您提供预期的结果。 但是,这是超出C标准的扩展,因此您应该检查编译器文档以确保它支持它。 此function在必须访问特定地址的内存的内核代码中并不常见。 它通常在用户程序中没用。

正如评论所提到的,您可能遇到的一个问题是,每次加载程序时,您的操作系统都会将程序加载到随机位置。 因此,您在一次运行中发现的地址将不是另一次运行中使用的地址。 此外,更改源和重新编译可能会产生不同的地址。

为了演示您可以使用指针访问以数字方式指定的地址,您可以检索地址并在单个程序执行中使用它:

 #include  #include  #include  int main(void) { // Create an int. int x = 0; // Find its address. char buf[100]; sprintf(buf, "%" PRIuPTR, (uintptr_t) &x); printf("The address of x is %s.\n", buf); // Read the address. uintptr_t u; sscanf(buf, "%" SCNuPTR, &u); // Convert the integer value to an address. int *p = (int *) u; // Modify the int through the new pointer. *p = 123; // Display the int. printf("x = %d\n", x); return 0; } 

显然,这在正常程序中没用; 这只是一个示范。 只有在您特别需要访问某些地址时才会使用此类行为。

为了从用户空间访问特定内存,我们必须使用mmap()将内存地址映射到程序虚拟地址,下面的C代码显示了实现:

获取包含“ABCDEFGHIJ”的文件“ test_file ”。

 #include  #include  #include  #include  int main(void) { char *map_base_addr; // Maping Base address for file int fd; // File descriptor for open file int size = 10; fd= open("test_file", O_RDWR); //open the file for reading and writing map_base_addr= mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);// Maping file into memory char *ch= map_base_addr; int i; /*Printing first 10 char*/ for(i=0; i 

输出将是:

 ABCDEFGHIJ AbCDzFGxIJ 

这个对我有用:

 #include  int main(int argc, char**argv) { int var = 7456; printf("Adress of var = %x, var=%d\n", &var, var); int *ptr = (int*)0x22cd28; printf(" ptr points to %x\n", ptr); *ptr = 123; printf("New value of var=%d\n", var); return 0; } 

节目输出:

 Adress of var = 22cd28, var=7456 ptr points to 22cd28 New value of var=123 

注意:

  1. 每次执行时地址通常都不相同。 当我尝试我的例子时,我必须运行它三次才能得到匹配的地址。

  2. char*可以指向任何地址(因为sizeof(char)= 1)。 指向较大物体的指针通常必须在偶数地址上对齐(通常可以被4整除)。

如果你在linux / windows / mac /上运行,你的问题并没有多大意义

http://en.wikipedia.org/wiki/Virtual_memory

只有在编写没有虚拟内存的设备或者正在编写操作系统本身时,才能执行此操作。

否则,您看到的地址不是RAM上的“真实”地址,操作系统会将它们转换为实际地址,如果没有地图将您的虚拟地址转换为真实地址,则可能会出现分段错误。 请记住,还有其他原因可能导致分段错误。