Verständnisproblem C und inline Assembler

#3733865
Lesenswert?

Ich habe ein paar einfach Funktionen die die Fakultät einer Zahl 
berechnen und wollte spaßeshalber mal es mit inline Assembler probieren.
Ich bekomme aber immer komisch Fehler Meldungen.
Daher hab ich mal was auskommentiert und schwupps geht es???
Kann mir jemand verraten was die "Magie" dahinter ist?

MfG

Im Anhang die der gesamte Quellcode, der gibt Compiler-Warnungen (gcc 
-std=gnu99).
Der Ausschnitt der nicht geht:
1
int fakultaet_pro(int a){
2
  int i;
3
  asm(
4
      "mov cx, %1\n\t"
5
      "mov ax, 1\n\t"
6
      "mov bx, 1\n\t"
7
      "wh: mul bx\n\t"
8
      "inc bx\n\t"
9
      "loop wh\n\t"
10
      "mov ah, 4Ch\n\t"
11
      "int 21h\n\t"
12
      "mov %0, ax"
13
      : "+r" (i)
14
      : "g" (a));
15
  return i;
16
}

Und hier die Änderung, die das richtige Ergebnis ausspuckt:
1
int fakultaet_pro(int a){
2
  int i;
3
  asm(
4
      "nop"
5
      /*"mov cx, %1\n\t"
6
      "mov ax, 1\n\t"
7
      "mov bx, 1\n\t"
8
      "wh: mul bx\n\t"
9
      "inc bx\n\t"
10
      "loop wh\n\t"
11
      "mov ah, 4Ch\n\t"
12
      "int 21h\n\t"
13
      "mov %0, ax"*/
14
      : "+r" (i)
15
      : "g" (a));
16
  return i;
17
}
Angehängte Dateien:
Persönliche Seite #3733932
Lesenswert?

Wenn ich's recht sehe, dann veränderst du

- ax
- bx
- cx
- ah

ohne dem COmpiler mitzuteilen, das sich da was ändert --> ja nach 
Aufrufsituation zeschießt das andere Werte.

Label "wh" ist schlecht, da bei Mehrfachverwendung (Inlining, 
Loop-Unroll, ...) das zu einem Fehler des Assembler führt --> Entweder 
lokale label wie 0, 1, 2, ... oder sowas wie .L_loop_%=
#3735048
Lesenswert?

Eigentlich war es ja nur aus Spaß aber mittlerweile will ich es endlich 
mal hinbekommen:

So sieht es jetzt bei mir aus:
1
int fakultaet_pro(int a){
2
  int i = 1;
3
  asm(
4
      "mov %%eax, %0\n\t"
5
      "mov %%bx, %1\n\t"
6
      "0: mul %%bx\n\t"
7
      "dec %%bx\n\t"
8
      "cmp %%bx,0\n\t"
9
      "ja 0\n\t"
10
      "mov %0, %%eax"
11
      : "+r" (i)
12
      : "g" (a)
13
      : "%eax", "%bx");
14
  return i;
15
}

Kompilieren tut es, aber es gibt immer Speicherzugriffsfehler...
Jemand einen Plan?
Danke :)
Gast #3735085
Lesenswert?

Damit dein C-Code nach dem Aufruf fakultaet_pro() korrekt abgearbeitet 
wird. Solltest du die im ASM-Code benutzten Register am Anfang der 
ASM-Anweisung auf den Stack mit PUSH sichern und am Ende mit POP 
wiederherstellen.

Ansonsten zerschiesst du Daten in den Registern die der C-Code eventuell 
noch braucht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren