3

我必须创建一个简单的基于堆栈的机器。指令集由5条指令组成;推,弹出,添加,多,结束。我接受一个包含指令部分 (.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?. . . 有点像两遍汇编器可能会这样做。

4

3 回答 3

2

只是为了增加 ugoren 的答案(有点 OT),我认为一个相对有趣的方法可能是用一个.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

文件堆栈.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);
}

文件生成文件:

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-23T08:02:50.323 回答
2

数组有什么问题?如果您知道所需的尺寸,它们应该可以工作。
机器代码中的地址实际上是数组中的索引。

对数组使用 32 位索引不是问题。当然,并非所有索引都是有效的——只有从 0 到数组大小的索引。但是你需要模拟4GB的内存,还是可以设置内存大小的限制?

于 2013-09-23T07:26:06.910 回答
2

内存系统的关键是限制内存的范围。在操作系统中,您只能访问内存的几个部分。

因此,在您的特定程序中,您可以说,有效程序可以包含从 0x00004000 开始的地址,并且您的机器可用的内存例如是 4 MB。

然后在您的程序中创建大小为 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).

如果您确实需要数组索引,只需从指针中减去虚拟内存的开头即可。

于 2013-09-23T09:08:52.243 回答