2012-06-02 4 views
0

아래의 가상 머신은 bin 포인터에서 스택 오프셋을 가져 와서 하나씩 증가시키는 스택 증분 명령어에서 segfaulting합니다. 값 -1을 사용하면 올바르게 작동하지만 bp[1] 오프셋을 통해 -1에 액세스하면 충돌이 발생합니다. 이것은 정말로 나에게 이해가 가지 않는다, 내가 뭘 잘못하고 있니?Mico C 가상 머신 세그먼트 화 오류

#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"); 
} 

답변

3

모든 변수는 서명되지 않습니다. -1을 저장하더라도 그것을 다시 읽을 때 4294967295가 표시됩니다.

+0

당신 말이 맞아, 감사 !!!! 어리석은 오류 :-) – Andrew

1

32 비트 컴퓨터입니까? enum typpe는 부호있는 정수입니다. 부호있는 정수 범위는 -0x80000000 ~ 0x7fffffff입니다.

부호있는 정수 -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]++; 

BUT, bp [1] == -1 ---> 부호없는 정수 !!! 그래서 코드 ...

sp[0xffffffff]++; 

귀하의 스택 크기 그래서 100 이다, 페이지 오류 (분할 오류) 발생 ...