我必须创建一个简单的基于堆栈的机器。指令集由5条指令组成: push、pop、add、mult、end。我接受具有指令节(.text)和数据节(.data)的源代码文件,然后必须通过模拟使用32位地址的内存系统将它们存储在内存中。
我必须存储在内存中的示例源代码文件可能是
.text
main:
push X
push Y
add //remove top two words in stack and add them then put result on top of stack
pop (some memory address) // stores result in the address
end
.data
X: 3 // allocate memory store the number 3
Y: 5
有什么关于如何做记忆系统的建议吗?我可能应该将数据存储在一个部分中(也许是一个数组?)我不能只使用数组索引,因为我需要在我的代码中使用32位地址。
编辑:当我将数字3和5分配给内存中的一个空间(在我的数据数组中)时,是否有一种方法可以将X和Y替换为实际地址?。。有点像两遍汇编器可以做到这一点。
发布于 2013-09-23 15:26:07
数组有什么问题?如果你知道你需要的尺寸,它们应该可以工作。
机器代码中的地址实际上是数组中的索引。
在数组中使用32位索引不是问题。当然,并不是所有的索引都是有效的-只有从0到数组大小的索引才是有效的。但是,您是否需要模拟4 4GB的内存,或者您可以设置内存大小的限制吗?
发布于 2013-09-23 16:02:50
为了补充一下ugoren的答案(还有一点OT),我认为一个相对有趣的方法可能是使用.stack
部分来扩展您的规范空间,该部分在默认情况下将初始化为空(就像您的示例中一样)。
这可以用来描述计算的预期中间阶段(保存/恢复某一时刻的实际状态)。
为了实现,我会使用非常简单的代码,比如
文件stack.h:
#ifndef STACK
#define STACK
#include <stdio.h>
/* here should be implemented the constraint about 32 bits words... */
typedef int word;
typedef struct { int top; word* mem; int allocated; } stack;
typedef stack* stackp;
stackp new_stack();
void free_stack(stackp);
void push(stackp s, word w);
word pop(stackp p);
/* extension */
stackp read(FILE*);
void write(stackp, FILE*);
#endif
文件stack.c:
/* example implementation, use - arbitrary - chunks of 2^N */
#include <stdlib.h>
#include "stack.h"
/* blocks are 256 words */
#define N (1 << 8)
stackp new_stack() {
stackp s = calloc(1, sizeof(stack));
s->mem = malloc((s->allocated = N) * sizeof(word));
return s;
}
void free_stack(stackp s) {
free(s->mem);
free(s);
}
void push(stackp s, int w) {
if (s->top == s->allocated) {
s->allocated += N;
s->mem = realloc(s->mem, s->allocated * sizeof(word));
}
s->mem[s->top++] = w;
}
word pop(stackp s) {
if (s->top == 0) { /* exception */ }
return s->mem[--(s->top)];
}
文件main.c:
#include "stack.h"
int main() {
stackp s = new_stack();
word X = 3;
word Y = 5;
push(s, X);
push(s, Y);
word Z = pop(s) + pop(s);
printf("Z=%d\n", Z);
free_stack(s);
}
文件makefile:
main: main.c stack.c
要构建:
make
要测试:
./main
Z=8
值得注意的是,WRT ugoren的答案是:我强调数据隐藏,这是实现的一个有价值的部分,将实际函数的详细信息保存在一个单独的文件中。在那里我们可以添加许多细节,例如关于最大堆栈大小(实际上没有强制执行),错误处理等。
编辑:获取推送单词的“地址”
word push(stackp s, int w) {
if (s->top == s->allocated) {
s->allocated += N;
s->mem = realloc(s->mem, s->allocated * sizeof(word));
}
s->mem[s->top] = w;
return s->top++;
}
发布于 2013-09-23 17:08:52
内存系统的关键是限制内存的范围。在操作系统中,你只能访问内存的几个部分。
因此,在您特定程序中,您可以说,有效的程序可以包含从0x00004000开始的地址,您的计算机可用的内存例如是4MB。
然后,在您的程序中创建4MB大小的虚拟内存空间,并存储它的开头。
下面是一个示例;请记住,这只是一个示例,您必须相应地调整参数。
virtual memory start - 0x00006000 (get from malloc, or static initialization. or whatever)
stack machine memory start - 0x00004000
offset - 0x2000 (to align addresses in you OS and in your stack machine, you have to add 0x2000 to the stack machine address to get pointer to your array (in reality the offset can be negative).
如果你确实需要一个索引来数组,只需从指针中减去虚拟内存的开头即可。
https://stackoverflow.com/questions/18953153
复制相似问题