在汇编语言中,我们有类似的说明
movl ax, [1000]
Run Code Online (Sandbox Code Playgroud)
这允许我们访问特定的内存位置.
但在C中我们可以做类似的事吗?
当然我知道使用asm()的内联汇编代码将允许你这样做.
但我想了解一些C特定技术来实现这一目标.
我尝试了以下代码并得到了分段错误
int *ptr=0xFE1DB124;
*ptr;
Run Code Online (Sandbox Code Playgroud)
由于下面给出的代码识别出内存位置,这再次令人困惑,
int var;
printf("\nThe Address is %x",&var);
Run Code Online (Sandbox Code Playgroud)
所以内存位置可用,但我仍然得到分段错误.
Eri*_*hil 10
常见的C编译器允许您设置一个整数的指针,并使用它来访问内存,它们将为您提供预期的结果.但是,这是超出C标准的扩展,因此您应该检查编译器文档以确保它支持它.此功能在必须访问特定地址的内存的内核代码中并不常见.它通常在用户程序中没用.
正如评论所提到的,您可能遇到的一个问题是,每次加载程序时,您的操作系统都会将程序加载到随机位置.因此,您在一次运行中发现的地址将不是另一次运行中使用的地址.此外,更改源和重新编译可能会产生不同的地址.
为了演示您可以使用指针访问以数字方式指定的地址,您可以检索地址并在单个程序执行中使用它:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
显然,这在正常程序中没用; 这只是一个示范.只有在您特别需要访问某些地址时才会使用此类行为.
为了从用户空间访问特定内存,我们必须使用mmap()将内存地址映射到程序虚拟地址,下面的 C 代码显示了实现:
取一个包含“ABCDEFGHIJ”的文件“ test_file ”。
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
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<size; i++)
fputc(*(ch+i),stdout);
printf("\n");
*(ch+1) = 'b';
*(ch+4) = 'z';
*(ch+7) = 'x';
/*Printing char after modification*/
for(i=0; i<size; i++)
fputc(*(ch+i),stdout);
printf("\n");
/* Finally unmap the file. This will flush out any changes. */
munmap(map_base_addr, size);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
ABCDEFGHIJ
AbCDzFGxIJ
Run Code Online (Sandbox Code Playgroud)