Forum: Compiler & IDEs Verständnisproblem C und inline Assembler


von Fer T. (fer_t)


Angehängte Dateien:

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
}

: Verschoben durch Moderator
von Rolf Magnus (Gast)


Lesenswert?

Ruf mal in deinem Programm fakultaet_pro() als erstes auf, vor den 
anderen Varianten. Tut's dann immer noch?

von Johann L. (gjlayde) Benutzerseite


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_%=

von Fer T. (fer_t)


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 :)

von Daniel A. (daniel-a)


Lesenswert?

Fer T. schrieb:
> Jemand einen Plan?

Nein, aber inline-assembler gefällt mir nicht, zu kompilerabhängig. Ich 
würde c und assembler trennen, mit gcc aus c code .o files machen, mit 
nasm aus asm code .o files machen, und dann alles zusammenlinken.

von Decius (Gast)


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.

von Rolf Magnus (Gast)


Lesenswert?

Decius schrieb:
> 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.

Aber dafür stehen die doch in der Clobber-Liste.
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.3

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.