mem_store和mem_load测试

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>uint8_t memory[1024] = {0}; // 模拟内存
FILE *log_file = fopen("log.txt", "w"); // 日志文件void mem_store(uint8_t * src, uint32_t addr, uint32_t count)
{fprintf(log_file, "mem write at %u\n", addr);memcpy(memory + addr, src, count);
}void mem_load(uint8_t * dst, uint32_t addr, uint32_t count){fprintf(log_file,"mem read at %u\n",addr);memcpy(dst, memory + addr, count);
}void print_memory(uint8_t *mem, size_t size) {for (size_t i = 0; i < size; i++) {printf("0x%02X ", mem[i]);if ((i + 1) % 16 == 0) { // 每行打印16个字节printf("\n");}}printf("\n");
}void output_memory_to_file(uint8_t *memory, size_t size, const char *filename) {FILE *file = fopen(filename, "w");if (file == NULL) {perror("Failed to open file");return;}for (size_t i = 0; i < size; i++) {// 输出地址和内容,每行显示一条记录// fprintf(file, "0x%08X 0x%02X\n", (unsigned int)(uintptr_t)(memory + i), memory[i]);// printf("0x%08lX 0x%02X\n", (uintptr_t)(memory + i), memory[i]);fprintf(file, "0x%08X 0x%02X\n", (unsigned int)i, memory[i]);}fclose(log_file);fclose(file);
}int main() 
{
// 准备数据
uint8_t src[] = {0x12, 0x34, 0x56, 0x78};
// 将数据写入内存的第 100 个字节位置
mem_store(src, 100, 4);
output_memory_to_file(memory, sizeof(memory), "mem_log.txt"); // 打印整个 memory 数组的内容uint8_t dst[4];        // 定义目标位置// 向 memory 中写入一些数据
memory[100] = 0xA1;
memory[101] = 0xB2;
memory[102] = 0xC3;
memory[103] = 0xD4;// 调用 mem_load 函数,将 memory 中从地址 100 开始的 4 字节数据读取到 dst 中
mem_load(dst, 100, 4);output_memory_to_file(memory, sizeof(memory), "mem_log.txt"); // 打印整个 memory 数组的内容}

mem_load

这段代码的作用是将一段内存数据从 memory 中读取到目标位置 dst,并记录读取操作的地址。

代码解析

void mem_load(uint8_t * dst, uint32_t addr, uint32_t count){fprintf(log,"mem read at %u\n",addr);memcpy(dst, memory + addr, count);
}
参数说明
  • uint8_t * dst:目标地址指针,表示要将读取的数据存储到的目标位置。
  • uint32_t addr:从 memory 中读取数据的起始地址。
  • uint32_t count:读取的数据字节数,即要从 memory 读取多少字节到 dst
执行步骤
  1. fprintf(log, "mem read at %u\n", addr);

    • 使用 fprintf 将读取操作的地址记录在日志文件 log 中,方便后续调试和追踪读取行为。
    • %u 用于输出无符号整数(addr),表示读取的起始地址。
  2. memcpy(dst, memory + addr, count);

    • 使用标准库函数 memcpy,从 memory 的起始地址 memory + addr 处开始读取 count 字节的数据,复制到目标地址 dst
    • memory + addr 表示要读取数据在 memory 中的偏移位置。
示例

假设 memory 是一个预先定义的内存空间,我们要从 memory 中读取一段数据,并存储到 dst 中。

示例场景
  • memory 是一块大小为 1024 字节的内存区域,已经有一些数据。
  • 我们想从 memory 的地址 100 处开始读取 4 字节数据,将它们放到 dst
uint8_t memory[1024];  // 定义模拟的内存
uint8_t dst[4];        // 定义目标位置// 向 memory 中写入一些数据
memory[100] = 0xA1;
memory[101] = 0xB2;
memory[102] = 0xC3;
memory[103] = 0xD4;// 调用 mem_load 函数,将 memory 中从地址 100 开始的 4 字节数据读取到 dst 中
mem_load(dst, 100, 4);
内存情况

执行完 mem_load(dst, 100, 4); 后:

  • log 文件会记录 “mem read at 100”,表示从 memory 的地址 100 处开始读取。
  • dst 数组的内容变为:
    dst[0] = 0xA1;
    dst[1] = 0xB2;
    dst[2] = 0xC3;
    dst[3] = 0xD4;
    

dst 成功接收了 memory 地址 100 处起始的 4 字节内容。

mem_store

这个函数 mem_store 将一个源缓冲区 src 中的数据存储到内存中的指定地址 addr 位置。它还会记录写入操作,打印一条日志信息,表明当前正在进行的写入操作。

让我们通过一个例子来看看它是如何工作的:

函数解释

void mem_store(uint8_t * src, uint32_t addr, uint32_t count){fprintf(log, "mem write at %u\n", addr);memcpy(memory + addr, src, count);
}
  • 参数说明:

    • src:指向要写入的数据源的指针。
    • addr:内存中的目标地址,表示要将数据写入的内存位置。
    • count:要写入的字节数。
  • 过程:

    • fprintf(log, "mem write at %u\n", addr);:将写入操作的信息(地址)记录到日志文件 log 中,便于调试或分析。
    • memcpy(memory + addr, src, count);:将 src 指向的数据复制到内存数组 memory 中,从 addr 开始连续写入 count 个字节。

举例

假设我们有以下情况:

  • memory 是一个大小为 1024 字节的全局数组,模拟计算机的内存。
  • src 是一个包含数据 0x12 0x34 0x56 0x78 的字节数组。
  • addr 为 100,表示我们要将数据写入内存的第 100 个字节开始的位置。
  • count 为 4,表示我们将写入 4 个字节的数据。

示例代码:

uint8_t memory[1024]; // 模拟内存
FILE *log = fopen("log.txt", "w"); // 日志文件// 准备数据
uint8_t src[] = {0x12, 0x34, 0x56, 0x78};// 将数据写入内存的第 100 个字节位置
mem_store(src, 100, 4);

执行后会发生以下事情:

  1. 日志输出
    日志文件 log.txt 中会写入一行内容:

    mem write at 100
    

    表示在内存的地址 100 处执行了一次写入操作。

  2. 内存状态变化

    • memory 数组的第 100 到 103 字节(总共 4 个字节)位置上,数据将被更新为 0x12, 0x34, 0x56, 0x78
    • memory 数组的状态(部分显示)将变为:
      memory[100] = 0x12;
      memory[101] = 0x34;
      memory[102] = 0x56;
      memory[103] = 0x78;
      

总结

mem_store 函数的作用是将指定的数据写入到内存的特定位置,类似于实际计算机中的存储操作。它还将写入操作记录到日志中,以便在程序运行时跟踪和调试内存的写入活动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/17192.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

从0开始创建Django项目-基础篇

文章目录 1、安装Django2、创建项目3、默认项目的介绍4、APP5、快速上手5.1 写一个页面5.2 templates模板5.3 静态文件5.3.1 static目录5.3.2 引用静态文件 6、模板语法7、请求和响应8、数据库操作8.1 安装第三方模块8.2 ORM8.3 案例:用户管理 1、安装Django pip install djan…

网络设备 - 这个有点难!

Linux 内核中的网络设备是整个网络通信的核心&#xff0c;它将硬件接口与内核的网络栈连接起来。对于许多初、中级学者而言&#xff0c;理解 Linux 网络设备的概念和工作机制可能显得复杂&#xff0c;但一旦掌握了这些内容&#xff0c;就能更深入地理解内核中的网络操作原理。本…

电商行业财一体化实施案例:如何通过对接实现多组织结算

电商行业财一体化实施案例&#xff1a;如何通过对接实现多组织结算 项目概述&#xff1a; 一家电子商务有限公司&#xff0c;专注于整合线上线下销售渠道&#xff0c;主营业务涵盖化妆品、日用品、乳制品、保健食品等产品的批发与零售。 公司背景与特色 主营业务&#xff1a…

动手学深度学习73 课程总结和进阶学习

1. 课程总结和进阶学习 https://c.d2l.ai/stanford-cs329p/ https://paperswithcode.com https://www.bilibili.com/video/BV1nA41157y4/?vd_sourceeb04c9a33e87ceba9c9a2e5f09752ef8 怎么建立知识库 2. QA 20 算法提取的特征和人的不一样&#xff0c;互补 21 很难预测未…

UE5材质篇 4 材质表面雨滴打落

materials 101的教程的灵感&#xff0c;特此记录一下 教程里本质上其实是先实验确定了湿滑表面的roughness和specular的值metallic这些&#xff0c;然后根据time来给表面的某些点这几个属性进行变换&#xff0c;主要是roughness和normal的变化 具体的变化是依赖了一张noise&a…

【论文分享】三维景观格局如何影响城市居民的情绪

城市景观对居民情绪的影响是近些年来讨论的热门话题之一&#xff0c;现有的研究主要以遥感影像为数据来源&#xff0c;进行二维图像-数据分析&#xff0c;其量化结果精确度有限。本文引入了三维景观格局的研究模型&#xff0c;通过街景图片及网络发帖信息补充图像及数据来源&am…

[代码+论文+讲解]2024数维杯A题:飞机激光测速中的频率估计问题

一、问题背景 空速是飞机相对于空气的速度&#xff0c;是飞行中需要监测的关键参数。空速与飞行状态如攻角和侧偏角密切相关。如果空速数据异常&#xff0c;很容易导致诸如失速等事故。因此&#xff0c;准确测量空速非常重要。 图1:空速激光测速的示意图 激光测速是一种可行的测…

[刷题]入门3.彩票摇奖

博客主页&#xff1a;算法歌者本篇专栏&#xff1a;[刷题]您的支持&#xff0c;是我的创作动力。 文章目录 1、题目2、基础3、思路4、结果 1、题目 链接&#xff1a;洛谷-P2550-彩票摇奖 2、基础 此题目考察数组、三重循环、自增操作的能力。 3、思路 写代码时候&#xf…

数据在内存中的存储

1&#xff1a;整数在内存中的存储 在前面我们已经在操作符那一章博客中引入了&#xff0c;原反补的概念。 正整数的原&#xff0c;反&#xff0c;补码相同。 负整数的三种码表示不同。 2&#xff1a;大小端字节序和字符序判断 1&#xff1a;什么是大小端 很明显&#xff0…

Java线程池:ThreadPoolExecutor原理解析

一、线程池的基本概念 1.1 线程池的定义 线程池是一组预先创建的线程&#xff0c;这些线程可以重复使用来执行多个任务&#xff0c;避免了频繁创建和销毁线程的开销。线程池的核心思想是通过复用一组工作线程&#xff0c;来处理大量的并发任务&#xff0c;减少系统资源消耗&a…

从0开始学习机器学习--Day26--聚类算法

无监督学习(Unsupervised learning and introduction) 监督学习问题的样本 无监督学习样本 如图&#xff0c;可以看到两者的区别在于无监督学习的样本是没有标签的&#xff0c;换言之就是无监督学习不会赋予主观上的判断&#xff0c;需要算法自己去探寻区别&#xff0c;第二张…

网页直播/点播播放器EasyPlayer.js网页web无插件播放器渲染页面出现倒挂的原因排查

EasyPlayer.js网页web无插件播放器属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式&a…

P3-3.【结构化程序设计】第三节——知识要点:while语句、do-while语句和for语句

视频&#xff1a; P3-3.【结构化程序设计】第三节——知识要点&#xff1a;while语句、do-while语句和for语句 知识要点&#xff1a;while语句、do-while语句和for语句 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 输出某班若干学生的成绩&#xff0…

面试时问到软件开发原则,我emo了

今天去一个小公司面试&#xff0c;面试官是公司的软件总监&#xff0c;眼镜老花到看笔记本电脑困难&#xff0c;用win7的IE打开leetcode网页半天打不开&#xff0c;公司的wifi连接不上&#xff0c;用自己手机热点&#xff0c;却在笔记本电脑上找不到。还是我用自己的手机做热点…

【重生之我要苦学C语言】深入理解指针6

深入理解指针6 sizeof和strlen的对比 sizeof 操作符 整型&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() {int a 10;printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(int));printf("%zd\n", sizeo…

虚拟展厅赋能线上品牌发布会,打造沉浸式体验

线上品牌发布会与虚拟展厅的结合&#xff0c;为企业提供了一个全新的、高效的品牌展示和营销平台。视创云展巧妙融合了3D导览、720全景沉浸体验、虚拟数字人交互、音视频通话以及个性化的互动功能&#xff0c;打造极具沉浸感的线上虚拟品牌发布会&#xff0c;深度赋能体验经济时…

shell编程(3)脚本参数传递与数学运算

声明!!! 学习视频来自B站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章 视频链接&#xff1a;泷羽sec 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 # 向脚本程序传参 脚本如下&#xff1a; echo 执行的文件名…

CTF-Crypto-affine

首页看描述 一个数学方程和一个flag&#xff0c;应该就是密文构成 y 17x-8 flag{szzyfimhyzd} e一下题目&#xff0c;字典给了一个线索&#xff0c;仿射&#xff0c;那应该就是仿射密码 e一下原理 简单来说&#xff0c;该加密方式&#xff0c;需要两个秘钥来进行加密和解密&a…

YOLOv8改进,YOLOv8结合DynamicConv(动态卷积),CVPR2024,二次创新C2f结构

摘要 大规模视觉预训练显著提高了大规模视觉模型的性能。现有的低 FLOPs 模型无法从大规模预训练中受益。在本文中,作者提出了一种新的设计原则,称为 ParameterNet,旨在通过最小化FLOPs的增加来增加大规模视觉预训练模型中的参数数量。利用 DynamicConv 动态卷积将额外的参…

【AI数字人整合包及教程】EchoMimic:开启数字人新纪元

在当今数字化转型的浪潮中&#xff0c;人工智能技术正以前所未有的速度重塑我们的生活方式。其中&#xff0c;阿里巴巴旗下蚂蚁集团推出的一款名为EchoMimic的开源AI数字人项目&#xff0c;正在引领一场前所未有的技术革命。本文将深入探讨EchoMimic的技术特点&#xff0c;与其…