2014-09-01 4 views
1

C++에서 인라인 asm에 문제가 있습니다. 빠른 strlen을 구현하려고하지만 작동하지 않습니다. __declspec(naked) 키워드 디버거는 입력 주소를 0x000000으로 표시합니다. 키워드를 사용하지 않으면 eax가 일부 휴지통을 가리키고 함수는 다양한 값을 반환합니다.C++ 인라인 어셈블러 함수에 인수 전달

여기에 코드입니다 :

int fastStrlen(char *input) // I know that function does not calculate strlen 
{        // properly, but I just want to know why it crashes 
    _asm      // access violation when I try to write to variable x 
    { 
     mov ecx, dword ptr input 
      xor eax, eax 
     start: 
      mov bx, [ecx] 
      cmp bl, '\0' 
      je Sxend 
      inc eax 
      cmp bh, '\0' 
      je Sxend 
      inc eax 
      add ecx, 2 
      jmp start 
     Sxend: 
      ret 
    } 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* test = "test"; 
    int x = fastStrlen(test); 
    cout << x; 
    return 0; 
} 

아무도 내가 잘못 뭐하는 거지 저를 지적 할 수 있습니까?

+0

'mov'가 아닌 'lea'를 원한다. 또한 길이를 반환하지 않으면 주소를 반환합니다. 16 비트 레지스터를' '\ 0' '과 비교하는 것은 여러분이 원하는 것을 할 수 없습니다. 그건 그렇고, 이것은 굉장히 빠르지 않을 것이고, 당신은 이것을하기 위해 정말로 asm이 필요하지 않습니다. – Jester

+0

@Jester mov가 작동하지 않으며 예, 나는 잘못된 값으로 돌아오고 있음을 알고 있지만 오류는 ESI 레지스터 사용으로 인한 것이라고 생각하여 이것을 변경했습니다. – encoree1337

+0

ABI에만 해당됩니다 (실제로 프로세서, 운영 체제, 컴파일러에 따라 다름). –

답변

1

__declspec(naked)을 사용하지 마십시오.이 경우 컴파일러는 에필로그 및 프롤로그 명령어를 생성하지 않으므로 컴파일러에서 사용자가 예상하는 것처럼 프롱 로그를 생성해야합니다. 그러면 fastStrlen 인수에 액세스 할 수 있습니다. 컴파일러가 무엇을 기대하는지 모르기 때문에 프롤로그를 생성하도록해야합니다.

즉, ret을 사용하면 발신자에게 돌아갈 수 없습니다. 이는 자신의 에필로그를 제공하고 있다는 것을 의미하기 때문입니다. 컴파일러에서 사용 된 프롤로그가 무엇인지 모르기 때문에이를 뒤집기 위해 구현해야하는 에필로그를 알지 못합니다. 대신 인라인 어셈블리 문 앞에 함수 내에서 선언 한 C 변수에 반환 값을 할당하고 일반 C return 문에서 해당 변수를 반환하십시오. 예를 들어 코드가 컴파일러의 런타임 라이브러리에서 strlen 구현에 개선 할 수 없습니다 귀하의 의견에 언급 한 바와 같이

int fastStrlen(char *input) 
{ 
    int retval; 
    _asm 
    { 
     mov ecx, dword ptr input 
     ... 
    Sxend: 
     mov retval,eax 
    } 
    return retval; 
} 

. 또한 길이가 짝수 인 문자열의 끝을 지나서 읽습니다. 문자열 끝에 도달 한 바이트가 메모리에 매핑되지 않으면 메모리 오류가 발생합니다.

+0

컴파일러가 뇌가 죽지 않는 한, 프롤로그없이'esp'에 상대적인 인수를 참조 할 수 있어야합니다. – Jester

+0

@Jester 그렇다면 인라인 어셈블리가 자체 프롤로그를 설정하지 않았다고 가정해야합니다. –

+0

좋은 지적입니다. – Jester