0

下面的虚拟机在我的堆栈增量指令中出现段错误,该指令从 bin 指针获取堆栈偏移量并将其加一。如果我使用值 -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");
}
4

2 回答 2

3

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

于 2012-06-02T13:38:08.913 回答
1

是32位机器吗?enum 类型是有符号整数。有符号整数范围是 -0x80000000 ~ 0x7fffffff。

你知道有符号整数 -1 ---> 无符号整数 0xffffffff。

看你的代码

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

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

你的编译器 make -1 ---> 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 ---> AND 无符号整数!!!所以你的代码...

sp[0xffffffff]++;

您的堆栈大小为 100。因此,发生了页面错误(分段错误)...

于 2012-06-02T13:47:19.583 回答