Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: rizor am 21. August 2012, 17:13

Titel: div64
Beitrag von: rizor 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
Titel: Re: div64
Beitrag von: Jidder 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).
Titel: Re: div64
Beitrag von: MNemo 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.
Titel: Re: div64
Beitrag von: Jidder 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.
Titel: Re: div64
Beitrag von: rizor 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
Titel: Re: div64
Beitrag von: Jidder 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.
Titel: Re: div64
Beitrag von: rizor am 21. August 2012, 21:48
Stimmt... Danke. Hatte ich nicht bedacht.
Jetzt klappt es, nachdem ich den ASM-Compiler überschrieben habe.
Titel: Re: div64
Beitrag von: MNemo 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