我试图创建一个可以读取二进制文件的简单VM,按照二进制文件中的指令(每个指令4个字 - 32位),然后在遵循所有指令后输出结果。
我目前处于项目的第一阶段,我正在尝试使用fread / fopen将我文件的内容读入缓冲区。在大多数情况下,代码类似于cplusplus.com上为fread提供的示例,但是我想找到一种方法将我的文件一次分成4个单词。我以前从未在如此低的水平上工作,并且在查明我是否正确地做这件事时遇到了问题,并且希望有人在这里可以帮助我确保我将文件分成4个正确的话。
FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;
pFile = fopen ( "test.bin" , "rb" );
if (pFile==NULL) {fprint("error, file null")}
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer, 4,lSize,pFile); //The error is here, if I use 1 instead of 4 there is no error output but I am not sure this would properly break the file into 4 words read at a time.
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
printf("%ld\n",lSize);
现在,当我运行此操作时,我收到一个错误,除非我更改了我评论回的行中的数字。
答案 0 :(得分:2)
将二进制文件表示为缓冲区是您的操作系统可以为您做的事情; mmap的手册页在C89中有一个工作示例(所以它是古董):
fd = open(argv[1], O_RDONLY);
...
if (fstat(fd, &sb) == -1) /* To obtain file size */
handle_error("fstat");
offset = atoi(argv[2]);
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
/* offset for mmap() must be page aligned */
...
if (argc == 4) {
length = atoi(argv[3]);
if (offset + length > sb.st_size)
length = sb.st_size - offset;
/* Can't display bytes past end of file */
} else { /* No length arg ==> display to end of file */
length = sb.st_size - offset;
}
addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
handle_error("mmap");
现在,addr
指向包含进程'地址空间中的输入文件的内存区域。
这将节省您在开始处理之前读取整个文件,因为您的操作系统可以自动只读取您实际访问的文件部分,而无需进一步操作。
另外,既然你正在写一个虚拟机(对你来说意味着什么!)你应该知道典型的进程内存结构,所以学习mmap
做的是一个很好的练习。