gpt4 book ai didi

c - C 中的内存映射地址(如何取消引用)

转载 作者:行者123 更新时间:2023-11-30 17:35:55 25 4
gpt4 key购买 nike

我想假装C中的数组是微处理器中的一个内存区域,这样我就可以在PC上编译一些代码。我编写了一个小程序来尝试使语法正确,但是当我更改访问变量的方式时,该程序无法运行,它要么崩溃,要么无法编译 - 已经晚了,我不明白为什么。请问这有什么问题吗?

// original code in microprocessor header that I need to change if I compile on the host
// BASE is simply a hex value that is later used as an address or a hex value
#define BASE (0x0000)
// used later in header like this (cannot change the way this is done)
#define OFFSET 0x0001
#define PERIPHERAL (BASE + OFFSET)
// also used like (also cannot change):
uint32_t var = PERIPHERAL | HEXMASK;

// here is how I intend to replace the uC specific code
// replace the BASE DEFINE with the next 2 lines of code:

// instead of writing to memory location, write to array of bytes instead, so declare it:
uint8_t BASE_memory[4] = {0, 0, 0, 0};
// define BASE as hex value that can be used as drop-in replacement in either of the 2 uses shown above
#define BASE ((uint32_t)(BASE_memory))

// now test usage
// access contents of BASE_memory[0]
printf("contents of BASE_memory[0] == %02x\n", *((uint32_t *)(BASE)));


// now I want to access PERIPHERAL, the second element of the array, i.e. BASE_memory[1]
printf("contents of BASE_memory[1] == %02x\n", *((uint32_t *)(PERIPHERAL)));

最佳答案

我认为您使用的是 64 位系统。

#include <stdint.h>

uint8_t BASE_memory[4] = {1, 2, 3, 4};

int func1()
{
return *(uint32_t *) (uint32_t) BASE_memory;
}

int func2()
{
return *(uint32_t *) (uintptr_t) BASE_memory;
}

这是 func1 的汇编输出:

leaq    _BASE_memory(%rip), %rax
movl %eax, %eax
movl (%rax), %eax

这是 func2 的程序集:

movl    _BASE_memory(%rip), %eax

您可以看到,如果将地址转换为 uint32_t,则需要执行一个额外步骤,将高位设置为零。地址是错误的,并且您会遇到段错误。这就是您使用 uintptr_tintptr_t 而不是 uint32_t 的原因。

关于c - C 中的内存映射地址(如何取消引用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22849074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com