gpt4 book ai didi

c - 用c表示内存

转载 作者:太空狗 更新时间:2023-10-29 15:59:16 25 4
gpt4 key购买 nike

我正在尝试用 C 编写一个指令集模拟器来模拟运行 ARM 的机器。我需要能够有效地表示 4GB 内存,经过一些挖掘,我找到了创建一个包含 1024 个指针的数组的解决方案,每个指针指向一个 4MB 的 block ,该 block 在首次使用时动态分配

#define MEMSIZE 1024    //1024 * 2Mb = 4Gb
#define PAGESIZE 4194304 //4 Mb
#define PAGEEXP 22 //2^PAGEEXP = PAGESIZE

uint32_t* mem[MEMSIZE];

我的问题是如何访问内存的某个地址?

我曾尝试将地址分解为索引和偏移量,如下所示,但这似乎只为索引和偏移量返回 0。 (memAdd 是我要访问的地址)

memIdx = memAdd >> PAGEEXP;
memOfs = memAdd & PAGESIZE;

一旦我有了地址,我用来读/写的函数如下:

void memWrite(uint32_t idx, uint32_t ofs, uint32_t val)
{
if(mem[idx] == 0)
mem[idx] = malloc(PAGESIZE);
*(mem[idx] + ofs) = *(mem[idx] + ofs) & val;
}

uint32_t memRead(uint32_t idx, uint32_t ofs)
{
if(mem[idx] == 0)
return 0;
else
return *(mem[idx] + ofs);
}

这些在我看来是正确的,但我仍然不是 100% 满意指针,所以这可能是错误的。

抱歉,如果这已经在某处讨论过,但我找不到与我需要的相关的任何内容(我的关键字非常广泛)

最佳答案

从逻辑上而不是在位级别开始。

每页有 4,194,304 字节。

然后,在算术上,要将线性地址转换为(页,偏移量)对,除以 4,194,304 得到页码,然后取余数得到页中的偏移量。

page = address / PAGESIZE;
offset = address % PAGESIZE;

由于您想有效地执行此操作并且这些是 2 的幂,因此您可以用 PAGESIZE 的以 2 为底的对数右移代替除以 PAGESIZE,即 22:

page = address >> PAGEEXP;

所以你的那部分代码是正确的。但是,要获得偏移量,您要做的是屏蔽除刚从页码中移出的所有位以外的所有位。为此,您必须使用 PAGESIZE - 1 进行 AND。

offset = address & (PAGESIZE - 1);

这是因为在二进制中,您从一个看起来像这样的数字开始(其中 p 是页码位,o 是偏移位):

address = ppppppppppoooooooooooooooooooooo

您想自己获取页码和偏移量。您显然想右移 22 位以获得页码:

page = addresss >> 22 = 0000000000000000000000pppppppppp

但是,如果您和pagesize(二进制00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000州),则您最多只有一个1位,它只会告诉您页码是否奇怪,甚至是奇数。没用。

你想要 AND 的是比它少一位,它是二进制 00000000001111111111111111111111,因此:

  ppppppppppoooooooooooooooooooooo 
& 00000000001111111111111111111111
-----------------------------------
= 0000000000oooooooooooooooooooooo

这就是您获得偏移量的方式。

这是一个一般规则:如果 N 是 2 的整数次幂,则除以 N 等同于右移 log(N)/log(2),并且这种除法的余数为与 (N-1) 相与。

关于c - 用c表示内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10843720/

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