Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet 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
-
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).
-
du hast das Semikolon in der ersten Zeile vergessen. gcc kennt das Register ecxxchg zurecht nicht.
Aber das Problem passt nicht wirklich zu:
Programmiertechnik:
Vermeide in Assembler zu programmieren, wann immer es geht.
-
Aber das Problem passt nicht wirklich zu:
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.
-
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
-
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.
-
Stimmt... Danke. Hatte ich nicht bedacht.
Jetzt klappt es, nachdem ich den ASM-Compiler überschrieben habe.
-
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