Problem mit inline assembler:



  • Hallo zusammen
    In der Schule haben wir gerade inline assembler und da sollten wir ein Programm schreiben, welches die Zeichen in einem c-string zählt. Leider stürzt jenes Programm ab und ich habe wirklich absolut keinen Plan, wieso!

    #include <stdlib.h>
    #include <stdio.h>
    
    #define MAX_LEN 10
    
    int main(){
     unsigned char  text[MAX_LEN+1];
     unsigned long len = 0;
    
     scanf("%s",text);
    
    	__asm{
          mov edx,DWORD ptr text
          mov ecx,0x00
      L1: cmp [edx],0x00 ;an dieser Stelle stürzt das Programm ab
          jne I1
          jmp EX
      I1: inc edx
          inc ecx
          jmp L1
      EX: mov len,ecx
    	}
    
     printf("%d",len);
    
     system("PAUSE");
     return 0;
    }
    

    Kennt sich vielleicht jemand damit aus?

    Lg Ishildur



  • Mich wundert eher, dass das ueberhaupt compiliert...
    Was soll das hier denn darstellen?

    L1: cmp [edx],0x00 ;an dieser Stelle stürzt das Programm ab
    

    Da ist ueberhaupt nicht festgelegt, wie gross die Konstante 0 ist, die verglichen werden soll. Anzunehmen, dass das als dword-Vergleich uebersetzt wird und deshalb das Ende eures Strings nicht gefunden wird. Irgendwann rennt der Pointer dann eben ins Nirvana.
    Probier mal sowas:

    L1: cmp byte [edx],0x00 ;Variante 1
    L1: cmp [byte ptr edx],0x00 ;oder alternativ auch so?
    


  • Hi Nabuo T
    Vielen dank für deine Hilfe
    Leider bin ich ein absoluter Neuling in der Welt der Assemblerprogrammierung. Nun verstehe ich allerdings, was du meinst! Leider funktionieren allerdings deine beiden Lösungsbeispiele nicht!

    Kannst du mir weiterhelfen?
    Ich habe es folgendermassen versucht:

    cmp [dl],0x00,

    was leider ebenfalls nicht funktionierte mit der Fehlermeldung: register must be base/index in first operand


  • Mod

    mov edx,DWORD ptr text
    

    das kann allerdings nicht funktionieren, wenn text nicht statisch ist.

    lea edx, text
    


  • Aber die Variable text ist doch ein pointer auf einen c-string?



  • Wenn dem so waere: Noch schlimmer. Dann muesstest du den Inhalt von text nach edx kopieren - also

    mov edx, [text]
    

    Und was meinst du mit "Leider funktionieren allerdings deine beiden Lösungsbeispiele nicht! "? Compiliert nicht? Weiterhin crashes?
    BTW: Du musst schon mit einem 32Bit-Register adressieren - anders geht hier nicht.


  • Mod

    Nobuo T schrieb:

    Wenn dem so waere: Noch schlimmer. Dann muesstest du den Inhalt von text nach edx kopieren - also

    mov edx, [text]
    

    Die Klammern sind an der Stelle nicht notwendig - das ist nicht nasm.


  • Mod

    camper schrieb:

    Nobuo T schrieb:

    Wenn dem so waere: Noch schlimmer. Dann muesstest du den Inhalt von text nach edx kopieren - also

    mov edx, [text]
    

    Die Klammern sind an der Stelle nicht notwendig - das ist nicht nasm.

    Ishildur schrieb:

    Aber die Variable text ist doch ein pointer auf einen c-string?

    Sieht das

    unsigned char  text[MAX_LEN+1];
    

    wie ein Pointer aus?



  • Ein Array in C ist doch immer ein Pointer?!


  • Mod

    Ishildur schrieb:

    Ein Array in C ist doch immer ein Pointer?!

    ein array ist und war schon immer ein array, ein zeiger ist und war schon immer ein zeiger, ein array ist nicht und war noch nie ein zeiger.



  • Und wieso funktioniert dann folgender Code? Wenn die Variable "str" kein Zeiger ist?

    void test(char *pStr){
    }
    
    int main(){
     char str[16];
     test(str);
     return 0;
    }
    

    Als ich C lernte, lernten wir, dass die Variable eines Arrays niemals das Array selbst sondern einen Zeiger auf das erste Element de jeweiligen Arrays enthält!


  • Mod

    Ishildur schrieb:

    Und wieso funktioniert dann folgender Code? Wenn die Variable "str" kein Zeiger ist?

    Weil str ein Array ist und es eine implizite Konvertierung in einen Zeigerwert (das heißt, ein rvalue) gibt. Das heißt nicht, dass ein Array ein Zeiger wäre. Der Ausdruck 0 kann zur Initialisierung jedes Zeigers verwendet werden - 0 selbst ist deswegen noch lange nicht selbst ein Zeiger. Weil es diese Konvertierung gibt, ist es möglich, ein Zeigerobjekt mittels eines Arrays zu initialisieren (genau das passiert, beim Funktionsaufruf).

    Als ich C lernte, lernten wir, dass die Variable eines Arrays niemals das Array selbst sondern einen Zeiger auf das erste Element de jeweiligen Arrays enthält!

    Das ist schlicht falsch. Punkt. Wahr ist, dass Arrays als solche nicht kopierbar (bzw. nicht zuweisbar - in C ist das sowieso im Grunde dasselbe) sind und daher nicht als Parameter oder Rückgabewert einer Funktion auftreten können (in C - in C++ können wir Referenzen auf Arrays bilden, womit die Kopierproblematik entfällt). Der Grund, weshalb Arrays nicht kopierbar sind, ist etwas zu komplex, um ihn hier mit wenigen Worten zu erklären - das ist ohnehin das falsche Forum dafür. Aus diesem Grunde wird man in C dann, wenn man eigentlich Arrays übergeben will, auf Zeiger ausweichen.


Anmelden zum Antworten