2016-11-20 1 views
0

J'ai donc cette fonction écrite en CC Assemblée inline génération exception non gérée

int transform (char * p) 
{ 
    if(*p!='-'){ 
     return 0; 
    } 

    p++; 
    if(*p == 'a') 
    { 
     return 1; 
    } 
    else if(*p == 'b') 
    { 
     return 2; 
    } 
    else 
    { 
     return 0; 
    } 
} 

et moi avons essayé de le traduire en assembleur en ligne ia32 comme celui-ci

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; 
} 

Quand j'ai la fonction écrite en C cela fonctionne parfaitement dans Visual Studio, mais quand je le change en assembly en ligne et exécute le code, j'obtiens une erreur en disant

Exception non gérée à 0x774e15ee dans proyect.exe: 0xC0000005: violation d'accès l'emplacement de lecture 0x01745388.

Est-ce que ce problème doit être avec le code ou est-ce un problème de studio visuel?

Je débogué mon code et a constaté que l'erreur est dans cette ligne

mov bl, [4*eax] 
+0

Comment 'transform' est-il appelé? Je remets en question la légitimité de déréférencer 'p' après' p ++'. – Bathsheba

+0

@Bathsheba Dans la fonction principale, je reçois comme argument de commande -b ou -a donc j'appelle la fonction de transformation pour voir si l'argument que j'ai reçu est valide. arg = argv [3]; puis int op = transformer (arg); – ravelinx

+1

Visual Studio vous permet de déboguer votre code en exécutant une instruction à la fois (appuyez sur F11 si je me souviens bien). Cela pointera sur une instruction particulière qui a généré l'exception. S'il vous plaît [modifier] votre message et écrire ce que cette instruction est - c'est une information très importante pour résoudre votre problème! – anatolyg

Répondre

1

Comme le débogueur indique, le problème est dans cette instruction:

mov bl, [4*eax] 

En regardant le code C, son intention est de charger le second octet de la chaîne en bl. Le pointeur sur le premier octet est eax, le pointeur sur le second octet est eax+1. Autrement dit, la commande appropriée est

mov bl, [eax+1] 

Sinon, vous pouvez le faire avec deux instructions:

inc eax 
mov bl, [eax] 

Ceci est plus conforme avec le code C:

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

mais fait le même.

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

L'idée est de faire avancer le pointeur dans EAX. Pas besoin de le multiplier!

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

Vous voulez lire l'octet après le '-', qui sera à eax+1, pas à 4*eax.