0

以下の私の仮想マシンは、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");
}
4

2 に答える 2

3

すべての変数は符号なしです。-1 を保存しても、読み返すと 4294967295 になります。

于 2012-06-02T13:38:08.913 に答える
1

32ビットマシンですか?列挙型は符号付き整数です。符号付き整数のスコープは -0x80000000 ~ 0x7ffffffff です。

符号付き整数 -1 ---> 符号なし整数 0xffffffff を知っています。

あなたのコードを見てください

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

binFile のタイプは uint32_t です。符号なし整数!!!

コンパイラは -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 ---> 符号なし整数!!! だからあなたのコード...

sp[0xffffffff]++;

あなたのスタックサイズは100です。だから、ページフォールト(セグメンテーションフォールト)が発生しました...

于 2012-06-02T13:47:19.583 に答える