#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
。
执行步骤
-
fprintf(log, "mem read at %u\n", addr);
- 使用
fprintf
将读取操作的地址记录在日志文件log
中,方便后续调试和追踪读取行为。 %u
用于输出无符号整数(addr
),表示读取的起始地址。
- 使用
-
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);
执行后会发生以下事情:
-
日志输出:
日志文件log.txt
中会写入一行内容:mem write at 100
表示在内存的地址 100 处执行了一次写入操作。
-
内存状态变化:
- 在
memory
数组的第 100 到 103 字节(总共 4 个字节)位置上,数据将被更新为0x12, 0x34, 0x56, 0x78
。 memory
数组的状态(部分显示)将变为:memory[100] = 0x12; memory[101] = 0x34; memory[102] = 0x56; memory[103] = 0x78;
- 在
总结
mem_store
函数的作用是将指定的数据写入到内存的特定位置,类似于实际计算机中的存储操作。它还将写入操作记录到日志中,以便在程序运行时跟踪和调试内存的写入活动。