2016-11-20 8 views
0

를 생성 그리고 내가 작성하는 기능이있을 때이C 인라인 어셈블리 그래서이 함수는 C</p> <pre><code>int transform (char * p) { if(*p!='-'){ return 0; } p++; if(*p == 'a') { return 1; } else if(*p == 'b') { return 2; } else { return 0; } } </code></pre> <p>에 쓴 처리되지 않은 예외

int trasform (char * p) 
    { 
     int result; 
     _asm 
     { 
      mov eax, p 
      mov ebx, 0 
      mov bl, [eax] 
      cmp bl, '-' ; 
       jne invalid 
       mov bl, [4*eax] 
      cmp bl, 'a' 
       jne isB 
       mov result, 1 
       mov eax, result 
      jmp out 
    isB: 
      cmp bl, 'b' 
       jne invalid 
       mov result, 2 
       mov eax, result 
      jmp out 
    invalid: 
      mov result, 0 
      mov eax, result 
    out: ; end 

    } 
    return result; 
} 

같은 조립 IA32 인라인 번역하려고 Visual Studio에서 완벽하게 작동하지만 인라인 어셈블리로 변경하여 코드를 실행하면 오류가 발생합니다.

proyect.exe에서 0x774e15ee의 처리되지 않은 예외 : 0xC0000005 : 0x01745388 위치를 읽는 액세스 위반.

이 문제는 코드와 관련이 있거나 Visual Studio의 문제입니까?

나는 내 코드를 디버깅하고 오류가이 줄

mov bl, [4*eax] 
+0

어떻게 변형됩니까? 나는'p ++ '다음에'p'를 역 참조하는 정당성에 의문을 제기한다. – Bathsheba

+0

@Bathsheba 주 함수에서 명령 인수 -b 또는 -a를 수신하므로 변환 함수를 호출하여 인수가 유효한지 확인합니다. arg = argv [3]; 그리고 나서 int op = transform (arg); – ravelinx

+1

Visual Studio에서는 한 번에 하나의 명령을 실행하여 코드를 디버깅 할 수 있습니다 (올바르게 호출 한 경우 F11 키를 누릅니다). 이것은 예외를 생성 한 특정 명령어를 가리 킵니다. 게시물을 [편집]하고이 지시 사항을 적어주십시오. 이것은 문제를 해결하는 데 매우 중요한 정보입니다! – anatolyg

답변

1

문제가이 명령에 :

mov bl, [4*eax] 

은 C 코드를 찾고, 그 의도는 bl에 문자열의 두 번째 바이트를로드한다. 첫 번째 바이트에 대한 포인터는 eax이므로 두 번째 바이트에 대한 포인터는 eax+1입니다.

inc eax 
mov bl, [eax] 

이 C 코드에 맞춰 더 : 즉 두 개의 지침 것을 할 수있는 적절한 명령 또는

mov bl, [eax+1] 

입니다입니다

p++; 
if (*p == ...) 

하지만 않습니다 같은.

3
mov bl, [4*eax] 
cmp bl, 'a' 

아이디어는 EAX에 포인터를 진행하는 것입니다 발견했다. 그것을 번식 할 필요가 없습니다! 디버거가 나타내는 바와 같이

inc eax    ;ptr++ 
mov bl, [eax] 
cmp bl, 'a' 
1

4*eax이 아닌 eax+1에있는 '-'뒤에 바이트를 읽으려고합니다.