Autor Thema: div64  (Gelesen 3455 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 21. August 2012, 17:13 »
Hi zusammen,

ich habe ein Problem mit meiner Assembler-Funktion zur Division einer 64-bit Zahl.

Hier der Code:
__asm__ volatile("div %%ecx"
                 "xchg %%ebx, %%eax;"
                 "div %%ecx;"
                 "xchg %%edx, %%ebx;" : "=a"(quot), "=b"(rem)
                                      : "a"(high), "b"(low),
                                        "c"(base), "d"(0));

Als Fehlermeldung bekomme ich ein "invalid register constraint".
Hatte gesehen, dass in Tyndur dann =A verwendet wird.
Da bekomme ich aber die Meldung, dass er das Register nicht in BREG finden kann.
Übersehe ich da was, oder ist mein GCC komisch eingestellt?

rizor
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 21. August 2012, 20:16 »
Der Unterschied zwischen a und A ist, dass bei A sich auf die Register eax und edx bezogen wird, also ein 64-Bit Wert angesprochen wird. Bei a wird nur eax verwendet. Du solltest A verwenden, wenn du ein 64-Bit Ergebnis haben willst. Ich kann das Problem leider nicht reproduzieren.

Welchen Compiler nutzt du (Version, 32/64-Bit, ist das ein OS X Compiler, etc was sonst noch komisch sein könnte) und mit welchen Flags kompilierst du? Du könntest auch mal versuchen "b"(low) durch "1"(low) zu ersetzen, um die BREG-Meldung zu beheben. Die 1 bezieht sich dann auf das "b" in "=b"(rem). Die Parameter sind durchnummeriert. 0 wäre z.B. "=a"(quot).
« Letzte Änderung: 21. August 2012, 20:19 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 21. August 2012, 20:25 »
du hast das Semikolon in der ersten Zeile vergessen. gcc kennt das Register ecxxchg zurecht nicht.

Aber das Problem passt nicht wirklich zu:
Zitat
Programmiertechnik:
Vermeide in Assembler zu programmieren, wann immer es geht.
« Letzte Änderung: 21. August 2012, 20:29 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 21. August 2012, 21:00 »
Aber das Problem passt nicht wirklich zu:
Zitat
Programmiertechnik:
Vermeide in Assembler zu programmieren, wann immer es geht.
Das in reinem C zu programmieren ist relativ ineffizient, weil man nur 32-Bit/32-Bit dividieren kann, wenn man keine libgcc hat.
« Letzte Änderung: 21. August 2012, 21:02 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 21. August 2012, 21:24 »
Ich verwende AS von CentOS.
Der scheint aber recht komisch konfiguriert zu sein, da er keine normalen Flags akzeptiert.
Mein ganzes Build-System wird in dem Fall von CMake aufgesetzt.
Also kann es auch daran liegen.

Hier die Flags:
/usr/bin/as  -Wall -Wextra -ansi -pedantic-errors -Wconversion -Wmissing-braces -Wswitch -Wno-long-long -fno-builtin -fvisibility=hidden -fPIC -O0 -g -m32
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 21. August 2012, 21:33 »
AS ist nicht GCC. Klar, dass der nicht alle Flags vom C-Compiler akzeptiert. Sicher, dass du den richtigen Aufruf gepostet hast?

Ein Problem wird vermutlich sein, dass du -fPIC verwendest. Das reserviert das Register ebx, um den Position Independent Code umzusetzen. Du könntest ein anderes Register verwenden, oder einfach das offen lassen und die Registerklasse "r" nehmen.
« Letzte Änderung: 21. August 2012, 21:35 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 21. August 2012, 21:48 »
Stimmt... Danke. Hatte ich nicht bedacht.
Jetzt klappt es, nachdem ich den ASM-Compiler überschrieben habe.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 21. August 2012, 22:02 »
Das in reinem C zu programmieren ist relativ ineffizient, weil man nur 32-Bit/32-Bit dividieren kann, wenn man keine libgcc hat.
Das ist richtig. Aber wer hat den keine libgcc? Die ist Teil von gcc. Wenn man 64bit gcc hat braucht man halt noch multilib support.

gcc -m32 -print-libgcc-file-name
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen