实现read函数时不要忘记对齐,其中讲义提示:
总是读取地址为 raddr & ~0x3u的4字节返回
所以需要把读进来的地址进行 & ~0x3u,得到对齐后的地址,
而后在把对齐后的物理地址转为虚拟地址guest_to_host(addr),
最后进行组合就ok了,例如:
地址: 0x80000000 0x80000001 0x80000002 0x80000003 数据: 0x12 0x34 0x56 0x78
如果 raddr = 0x80000003,对齐后的地址是 0x80000000,读取的 4 字节数据组合后为 0x78563412,该数据将作为函数的返回值。
最终实现代码如下:
static word_t pmem_read(paddr_t addr) { paddr_t adapt_addr = addr & ~0x3u; uint8_t *ret = guest_to_host(adapt_addr); word_t data; for (int i = 0; i < 4; i++){ data |= ret[i] << ( i * 8); } return ret; }
利用或操作进行拼接。
写操作同理,讲义中提示:
extern "C" void pmem_write(int waddr, int wdata, char wmask) { // 总是往地址为`waddr & ~0x3u`的4字节按写掩码`wmask`写入`wdata` // `wmask`中每比特表示`wdata`中1个字节的掩码, // 如`wmask = 0x3`代表只写入最低2个字节, 内存中的其它字节保持不变 }
根据刚才的对齐规则,掩码也是相同机理
extern "C" void pmem_write(int waddr, int wdata, char wmask) { //host_write(guest_to_host(addr), len, data); paddr_t adapt_addr = waddr & ~0x3u; uint8_t *vaddr = guest_to_host(adapt_addr); for(int i = 0; i < 4; i++){ if (wmask & (1 << i)) { vaddr[i] = (wdata >> (i * 8)) & 0xFF; } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界