Mico C虚拟机分段故障

时间:2012-06-02 13:21:05

标签: c vm-implementation

下面的虚拟机是我的堆栈增量指令的segfaulting,它从bin指针获取堆栈偏移量并将其递增1。如果我使用值-1这可以正常工作,但是当我通过-1偏移量访问bp[1]时,它会崩溃。这对我来说真的没有意义,我做错了什么?

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>

typedef enum {PUSH,STACKINC,EXIT} opCodes;
char * opCode[] =  {"Push","Stack Increment","Exit"};

typedef struct VirtualMachine
{
    uint32_t * sp;          /* Stack Pointer   */
    uint32_t * bp;          /* Bin Pointer     */
    uint32_t stack[100];    /* VM stack        */
} VM;

void processVM(VM * vm)
{
    uint32_t * bp = vm->bp;
    uint32_t * sp = vm->sp;
    printf("OP: %s\n",opCode[bp[0]]);

    switch (bp[0])
    {
    case PUSH:      sp[0] = bp[1]; sp++; bp+=2;     break;
    case STACKINC:  sp[bp[1]]++; bp+=2;             break;
    }

    vm->bp = bp;
    vm->sp = sp;
    /* Set out stack and bin pointers back */
}


int main()
{
    uint32_t binFile[] = {PUSH,1,PUSH,2,PUSH,3,STACKINC,-1,EXIT};

    VM myVM;
    myVM.bp = binFile;
    myVM.sp = myVM.stack;

    while(myVM.bp[0] != EXIT)
    {
            processVM(&myVM);
            usleep(200000);
    }
    printf("VM done executing\n");
}

2 个答案:

答案 0 :(得分:3)

所有变量都是无符号的。即使你存储-1,你在阅读时也会得到4294967295.

答案 1 :(得分:1)

是32位机器吗? 枚举typpe是有符号整数。有符号整数范围是-0x80000000~0x7fffffff。

你知道有符号整数-1 ---&gt;无符号整数0xffffffff。

查看您的代码

uint32_t binFile[] = {PUSH,1,PUSH,2,PUSH,3,STACKINC,-1,EXIT};

binFile的类型是uint32_t。无符号整数!!!

你的编译器make -1 ---&gt; 0xffffffff(无符号整数)。

让我们看看这个代码

switch (bp[0])
    {
    case PUSH:      sp[0] = bp[1]; sp++; bp+=2;     break;
    case STACKINC:  sp[bp[1]]++; bp+=2;             break;
    }

...详细

    case STACKINC:  sp[bp[1]]++; bp+=2;             break;

更详细......

sp[bp[1]]++;

你想要吼叫......

sp[-1]++;

,但 bp [1] == -1 ---&gt;和无符号整数!!! 所以你的代码......

sp[0xffffffff]++;

您的筹码量是100。 因此,出现了页面错误(分段错误)...