![]() |
DEUTSCHE VERSION |
|
![]() |
Links | | | Forums | | | Comments | | | Report news |
![]() |
Chat | | | Polls | | | Newsticker | | | Archive |
![]() |
amiga-news.de Forum > Programmierung > gcc und Assembler Code | [ - Search - New posts - Register - Login - ] |
-1- | [ - Post reply - ] |
2005-10-25, 10:45 h Mad_Dog Posts: 1944 User |
Hallo, Ich bin gerade dabei ein altes Programm (stammt nicht von mir) vom Borland C++ Builder auf gcc zu "portieren". Unter anderem ist auch x86 Assembler Code enthalten: code:unsigned short int high(unsigned long a) { unsigned short int back; asm { push eax mov eax,[a+2] mov back,ax pop eax }; return back; } Leider meckert der gcc (ist gcc für x86). Klar kann man das auch anders machen, aber ich wüsste trotzdem gerne, wie das ANSI C++ konform auszusehen hat. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-25, 20:04 h Mazze Posts: 263 User |
@Mad_Dog: Ganz einfach: ANSI C++ kennt kein "asm". Wenn doch alle Probleme so einfach wären :-) Im ernst: Soweit ich weiß, hat GCC einen plattformunabhängigen Assembler. Da Du das sowieso umschreiben müsstest, kannst Du auch gleich C nehmen. -- Meine Homepage [ - Answer - Quote - Direct link - ] |
2005-10-26, 09:21 h Mad_Dog Posts: 1944 User |
Zitat: Also laut Bjarne Stroustrup's "Die C++ Programmiersprache" kennt C++ sehr wohl auch Assembler Code Sequenzen. Eigentlich müsste es so funktionieren, wie in meinem Posting dargestellt - geht aber irgendwie nicht... ![]() -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-26, 09:41 h gni Posts: 1106 User |
Zitat:Nein. Zitat:Und das ist auch gut so! Machs in C(++) und der Fall ist erledigt. [ - Answer - Quote - Direct link - ] |
2005-10-26, 09:45 h gni Posts: 1106 User |
Zitat:Was soll ein "plattformunabhängiger Assembler" sein? Wenn Du x86 Befehle verwendest, dann eignet sich das nur für x86. Zudem benutzt der GCC eine andere Art von Inline-Asm. Das kann man im Abschnitt "extended Asm" der GCC-Dokumentation nachlesen. [ - Answer - Quote - Direct link - ] |
2005-10-26, 09:45 h Solar Posts: 3680 User |
Zitat: Nicht ganz. Aus besagtem Buch: Zitat: Das heißt, Du must in jedem Fall die Dokumentation Deines Compilers befragen, da C++ über den Inhalt, Syntax etc. des string-literals keine Aussagen macht. http://www.mega-tokyo.com/osfaq2/index.php/InlineAssembly http://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Extended-Asm.html#Extended-Asm [ Dieser Beitrag wurde von Solar am 26.10.2005 um 09:46 Uhr editiert. ] [ - Answer - Quote - Direct link - ] |
2005-10-26, 09:48 h Solar Posts: 3680 User |
Zitat: GNU 'as' aus dem binutils-Package. Die "plattformunabhängigkeit" bezieht sich darauf, das die 'as'-Varianten für die unterschiedlichen Plattformen soweit möglich dieselben Kommandozeilenparameter und dieselbe Syntax haben. Zitat: Und eben dieses, durch ein einleitendes "asm" gekennzeichnetes Compiler-spezifisches Verhalten ist durch den C++-Standard abgesegnet. [ - Answer - Quote - Direct link - ] |
2005-10-26, 12:01 h Mazze Posts: 263 User |
Zitat: Ups, ich hatte angenommen, dass der inline-assembler prozessorunabhängig ist. -- Meine Homepage [ - Answer - Quote - Direct link - ] |
2005-10-26, 12:21 h Solar Posts: 3680 User |
Kann er nicht. GCC gibt's u.a. für 68k, PPC, x86... jeder dieser Prozessoren mit eigenen Befehlen, Adressierungsarten etc. - ein wirklich plattformunabhängiger Assembler ist nicht möglich. GNU 'as' ist halt das den Maschinencode erzeugende "Backend" von GCC. Da hat man drauf geachtet, das der Teil von GCC, der z.B. vom PPC-'as' auf den 68k-'as' angepaßt werden muß, möglichst klein ist. Das ist aber auch schon alles - ein PPC-Assembler kann mit "SYSCALL" oder "IDIV" nun einmal nichts anfangen... [ - Answer - Quote - Direct link - ] |
2005-10-26, 13:54 h Mad_Dog Posts: 1944 User |
@Solar: Danke! Natürlich hab diesen Code-Abschnitt jetzt durch "normale" C/C++ Lowlevel Operationen ersetzt - ist ja auch einfacher. ![]() code:// folgendes gilt nur für LittleEndian Systeme, // deren breite für Long exakt 4 Byte ist. inline unsigned short int low(unsigned long a) { return (int)a; // loword holen }; inline unsigned short int high(unsigned long a) { return (int)(a>>16); // highword holen }; Das gilt aber nur für x86. Das Ziel ist es, das Programm (über 300000 Zeilen C++ Code) von Borland C++ Builder (x86 Windows) auf gcc (UltraSparc Solaris) zu portieren. Und da ist leider jede Menge Zeug drin, was nicht nach ANSI/ISO Standard ist. ![]() -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 26.10.2005 um 17:21 Uhr editiert. ] [ - Answer - Quote - Direct link - ] |
2005-10-26, 17:08 h gni Posts: 1106 User |
Zitat:Der Kommentar ist falsch. Der Code funktioniert auch auf nicht-LittleEndian Systemen... Zitat:Du solltest mit "& 0xffff" den Wert begrenzen. Und warum mit (int) casten?code:inline unsigned short int low(unsigned long a) { return (int)a; // loword holen }; Zitat:Warum soll der obige Code nur auf x86 laufen?code:Das gilt aber nur für x86.inline unsigned short int high(unsigned long a) { (int)(a>>16); // highword holen }; Zitat:Byteorder und Typgröße ist nur interessant, wenn Du mit Binärdaten einlesen/speichern mußt. [ - Answer - Quote - Direct link - ] |
2005-10-26, 17:13 h Mad_Dog Posts: 1944 User |
Zitat: "Laufen" tut er sicher auch auf UltraSparc Systemen - nur macht er da nicht das richtige. Überleg Dir mal, was passieren würde, wenn die Byteorder anders wäre (Big Endian statt Little Endian) und ich den Shift-Operator verwende... Zitat:Zitat:Byteorder und Typgröße ist nur interessant, wenn Du mit Binärdaten einlesen/speichern mußt. Und genau darum geht's bei der Sache. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 26.10.2005 um 17:21 Uhr editiert. ] [ - Answer - Quote - Direct link - ] |
2005-10-26, 17:31 h Holger Posts: 8116 User |
Zitat:Solange Du nicht mit pointern auf dem Speicher operierst, ist es vollkommen unerheblich, in welcher Reihenfolge die bytes im Speicher liegen. (x&0xff) betrifft immer das niederwertigste Byte, (x&0xff)>>8 immer das nächsthöhere. Zitat:Dann sollte der Code so gestaltet werden, daß bereits beim Einlesen/Speicherzugriff die Umwandlung stattfindet. Aus einem Speicherbereich ein long zu lesen, um ihn dann mittels shiften und maskieren umzudrehen, ist unlogisch/schlecht lesbar UND ineffizient.Zitat:Und genau darum geht's bei der Sache. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2005-10-27, 09:17 h gni Posts: 1106 User |
Zitat:Du solltest Deinen Hinweis selber befolgen. Dann fällt Dir hoffentlich auf, das der von Dir gezeigte Code auf jeder Byteorder funktioniert. Zitat:Dann mach das Ändern der Bytereihenfolge auch an der richtigen Stelle. Mit denen von Dir geposteten Funktionen erreichst Du _nichts_. FWIW, Du solltest mit char-Feldern arbeiten, wie zb. die GNU binutils.Zitat:Und genau darum geht's bei der Sache. [ - Answer - Quote - Direct link - ] |
2005-10-27, 09:53 h Mad_Dog Posts: 1944 User |
Zitat: Ich glaube, wir reden aneinander vorbei. Hier geht's nicht darum eine Umwandlung von Little auf Big Endian vorzunehmen, sondern das High- bzw Low- Word aus einem Long zu lesen, also die oberen oder unteren 16 Bit von 32. Hier nochmal ein Beispielcode: code:#include <cstdlib> #include <iostream> using namespace std; int main(int argc, char *argv[]) { cout << "int : " << sizeof(int) << " byte" << endl; cout << "short int : " << sizeof(short int) << " byte" << endl; cout << "char : " << sizeof(char) << " byte" << endl; cout << "long : " << sizeof(long) << " byte" << endl; const long l = 0xA4B3C2D1; unsigned short hi,lo; lo = (int)l; // loword holen hi = (int)(l>>16); // highword holen cout << hex << l << endl; cout << hex << "lo=" << lo << endl << "hi=" << hi << endl; cin.get(); return 0; } Die Sache mit der "Wandlung" habe ich mal in eimem BMP Texturloader für Amiga gebraucht... dort habe ich tatsächlich den Shifter zum Vertauschen der Bytes verwendet. Siehe hier: ftp://de.aminet.net/pub/aminet/dev/src/GL_BMP_Load_11.lha -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-27, 12:38 h Holger Posts: 8116 User |
Zitat:Und dieser Code macht auf allen Systemen das Gleiche, egal ob BigEndian oder LittleEndian. Glaub doch einfach mal denen, die schon etwas länger mit C zu tun haben. (Obwohl das nicht unbedingt C-spezifisch ist.) Nur, wofür das gut sein soll, ist nicht klar. Dieser Code hat nichts mit I/O oder anderer Form von externen Daten zu tun. Zitat:DAS ist ja auch völlig anderer Code. Das BMP-Format benutzt tatsächlich eine definierte Endianess, die von der des Systems abweichen kann... mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ Dieser Beitrag wurde von Holger am 27.10.2005 um 12:39 Uhr editiert. ] [ - Answer - Quote - Direct link - ] |
2005-10-27, 12:50 h Mad_Dog Posts: 1944 User |
Zitat: Hab's zwar noch nicht ausprobiert, aber wenn Du das sagst. ![]() Ich dachte eben, wenn die Reihenfolge anders ist, würde es eine Rolle spielen, ob ich nach links oder rechts schiebe... Zitat:Zitat:DAS ist ja auch völlig anderer Code. Das BMP-Format benutzt tatsächlich eine definierte Endianess, die von der des Systems abweichen kann... Im aktuellen Fall geht es darum, gds Dateien einzulesen. Aber ich denke, es hat sich erübrigt, da diese Codesequenz überflüssig geworden ist. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 27.10.2005 um 12:51 Uhr editiert. ] [ - Answer - Quote - Direct link - ] |
2005-10-27, 15:21 h Holger Posts: 8116 User |
Zitat:Es spielt eine Rolle, ob Du nach links oder rechts schiebst. Ein Bit nach links schieben ist gleichbedeutend mit Verdoppeln, eins nach rechts mit Halbieren. Nun stell Dir mal vor, wie es sich programmieren würde, wenn man auch noch bei Multiplikation und Division die Byteorder berücksichtigen müßte... ![]() mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2005-10-27, 18:05 h Mad_Dog Posts: 1944 User |
Zitat: Das war eben mein Denkfehler: Nicht links oder rechts, wie wenn man die Zahl aufs Papier schreibt, sondern n Bit in Richtung höherwertiges oder niederwertiges Bit schieben. Danke! ![]() -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-27, 21:17 h Holger Posts: 8116 User |
Zitat: Hmm, wenn Du die Zahl binär aufschreibst und wie die meisten Mitteleuropäer von links nach rechts schreibst, dann kommts doch hin. Ansonsten wärst Du der erste mir bekannte Mensch, der Zahlen in LittleEndian aufschreiben würde. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2005-10-28, 09:27 h Mad_Dog Posts: 1944 User |
Zitat: Also wenn ich einen Schreibtischtest für ein Programm mache, oder mir eine Binärdatei anschaue (oder gar als Hexzahlen ausdrucke), dann habe ich die Zahlen sehr wohl als Little Endian vor mir, falls diese im Rechner auch tatsächlich so gespeichert werden. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-28, 11:12 h Solar Posts: 3680 User |
C selbst kennt kein "byte". Es kennt nur char, short, int, long, (long long). Und im Hinblick auf die Shift-Operatoren steht das höchstwertigste Bit links. Die Probleme mit Low / Big Endian gibt's immer erst beim Einlesen und Rausschreiben, z.B. wenn Du einen long einliest, der aber tatsächlich aus zwei shorts besteht, oder auf einer Maschine mit Endianess X Binärdaten einliest, die auf einer Maschine mit Endianess Y geschrieben wurden. Solange Du Dich auf einer Maschine bewegst und die "richtigen" Datentypen für den Inhalt verwendest, merkst Du in C von Endianess gar nichts. Und was Dein Beispiel angeht... gesunde Paranoia anlegen und Ausgabefunktionen, Hexeditor etc. auf implizite Konvertierungen prüfen... [ - Answer - Quote - Direct link - ] |
2005-10-28, 12:01 h Mad_Dog Posts: 1944 User |
Zitat: Eben. x86 und UltraSparc sind hier eben verschieden. Die gds Datei wird von Cadence unter Solaris geliefert und soll in einem Programm auf Windows verarbeitet werden, welches es jetzt nach Solaris zu portieren gilt. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-28, 12:09 h Holger Posts: 8116 User |
Zitat: Du scheinst Dir selbst das Leben schwer machen zu wollen. Ich bin mir sicher, daß Dein Schreibtisch von Endianess erst mal keine Ahnung hat. Und es ist auch nicht sinnvoll, sich ein Datum mit einem HexEditor byteweise ausgeben zu lassen, wenn es sich bei dem Wert nicht um eine Abfolge von bytes handelt. Wenn Du einen Algorithmus in Gedanken durchgehen willst, dann solltest Du bei einer Zahl auch nur an eine Zahl denken und nicht an eine Folge von n bytes und an deren Reihenfolge. Und dann frage auch den Debugger nach dem int-Wert und nicht nach eine hexadezimalen Abfolge von bytes. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2005-10-28, 12:48 h Mad_Dog Posts: 1944 User |
@Holger: Du wirst es doch wohl nicht bestreiten wollen, daß es durchaus sinnvoll ist, eine Binärdatei in einem Hexeditor anzuschauen, wenn man für das jeweilige (binär) Format (z.B. gds) eine Lade/Speicherroutine schreiben will, oder? Also ich für meinen Teil drucke mir in solch einem Fall eine kleine Testdatei aus - dann kann ich darin munter Stellen mit dem Textmarker markieren, Anmerkungen dazukritzeln usw. . -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-28, 13:55 h Holger Posts: 8116 User |
Zitat:Doch, halte ich für sinnlos. Entweder ich besitze eine Dokumentation für das Dateiformat oder ich lasse es bleiben, insbesondere würde ich lassen, wenn ich nichtmal verstehe, was die Operatoren in C machen. Wenn ich dagegen eine Laderoutine für ein bekanntes Format schreiben will, wäre es Zeitverschwendung, eine Datei im Hexdump anzuschauen, wenn ich die Laderoutine selbst mit printf's füllen kann, die den jeweiligen Wert in seiner natürlich Form, also Zahlen als Dezimalwert in ihrem richtigen Wertebereich statt als bytes, und Flags als Hex-Wert oder sogar symbolisch ausgeben. Das gibt mir viel mehr Informationen und kann mit einem Dutzend Beispieldateien aufgerufen oder auch schrittweise debugged werden. Zitat:und heraus kommt eine Laderoutine, die genau diese eine Datei einlesen kann? Ein Hexviewer kann in wenigen Fällen den Debugvorgang ergänzen, aber da weder Mensch noch Computer auf ein einem HexDump operieren, ist er keinesfalls die erste Wahl bei den Hilfmitteln. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
2005-10-28, 14:01 h Solar Posts: 3680 User |
Zitat: Nur wenn einem bewußt ist, das ein Hexeditor durchaus selbst eine Umwandlung zwischen Endianess vornehmen mag. Gibt Dein Hexdumper in "native format" aus, immer Big Endian, oder immer Little Endian? Solange Du diese Frage nicht aus der Hüfte beantworten kannst, hast Du bei solchen Reverse-Engineering-Versuchen ein Problem. Von den übrigen Problemen, die Holger angesprochen hat, mal ganz abgesehen... [ - Answer - Quote - Direct link - ] |
2005-10-28, 14:01 h Mad_Dog Posts: 1944 User |
[quote] Original von Holger: Zitat: Hab ich je behauptet, daß ich blindes Reverse Engineering betreibe? Natürlich habe ich eine Dokumentation zum Dateiformat. Allerdings kann es nicht schaden, wenn man ein konkretes Beispiel anschaut und im Falle einer Speicherroutine das ist Ergebnis mit dem soll Ergebnis vergleicht. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2005-10-28, 19:40 h Holger Posts: 8116 User |
Zitat:Ich ja auch nicht. Wenn ich eine Dokumentation zu einem Dateiformat habe, brauche ich aber keinen Hex-Dump. Zitat:Das "Anschauen" geht aber viel leichter, wenn man statt auf einen Hexdump auf den Output einer selbst geschriebenen Leseroutine schaut, die die Einträge der Struktur in sinnvollen, den Datentypen entsprechenden Ausgabeformaten ausgibt. Aber das hatte ich oben ja schon geschrieben. Dann hast Du nämlich hinterher auch schon die Laderoutine fertig. Und dieser source-code ist besser als jede Notiz auf einem Schmierpapier. Denn diese Art der Notiz kann sowohl von der Maschine als auch jedem anderen Programmierer verstanden werden, mit dem Du Dich über das Dateiformat oder Deine Software austauschen möchtest. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Answer - Quote - Direct link - ] |
-1- | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > gcc und Assembler Code | [ - Search - New posts - Register - Login - ] |
![]() |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2025 by amiga-news.de - all rights reserved. |
![]() |