ubuntuusers.de

Assembler: gcc und as?!

Status: Ungelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

infty999

Anmeldungsdatum:
27. Mai 2012

Beiträge: Zähle...

Hallo Leute, ich habe heute angefangen mir mal Assembler anzuschauen und ich musste glücklicherweise feststellen, dass das schon in Ubuntu mit drin ist. Welch ein Glück. Allerdings bin ich in dem zusammenhang über gcc und as als Assembler gestolpert. Gibt es dabei Unterschiede? Und eventuell Webseiten wo ich als Referenz alles wichtige finde um die notwendigen Anpassungen durchzuführen, sofern meine Tutorials nicht mit den Assemblern konform sind? Fände ich toll.

Bedanke mich schonmal im voraus für eure Hilfe 😉

Gruß Infty

PS: Evtl kann ja jemand sagen welcher davon praktischer ist, da ich noch in C programmiere. Und auch C++ selbstverständlich 😀

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

Servus,

ich würde mit as und ld anfangen und nicht den gcc als Frontend dafür benutzen. Ist für den Anfang übersichtlicher, finde ich. Wobei gerade am Anfang die Bedienung der Tools eigentlich nicht so wichtig ist, da es dir am allgemeinen Überblick und Wissen mangeln wird, wenn du vorher noch kein Assembler gemacht hast. Generell ist die Dokumentation im Netz nicht besonders gut und sehr verstreut. Es programmieren halt kaum noch Leute in Assembler – und wenn, dann wissen die ziemlich genau, was sie tun. Bedarf an Tutorials gibt es eigentlich kaum.

Ganz wichtig ist zum Beispiel, dass du dich mit der Syntax vom GNU-Assembler vertraut machst: http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax. Leider hilft einem der Rest des Wikibooks nicht so wirklich weiter.

Dann könntest du dir anschauen, wie das mit den Syscalls unter Linux funktioniert, damit du einfache Ausgaben tätigen kannst (über „write()“) und vorallem das Programm sauber beenden kannst („_exit()“).

Da ich auf Anhieb nicht weiß, wo das in einem „Tutorial“ auftauchen könnte, ist hier ein HelloWorld („hello.s“):

.data                          /* data section begins */
hello:                         /* a label called "hello" */
    .string "Hello, world!\n"  /* "string" directive creates a c-string */

.text                  /* text/code section begins */
.global _start         /* makes "_start" visible to ld */
_start:                /* the "_start" label followed by instructions */
    movl $4, %eax      /* syscall #4 is write() */
    movl $1, %ebx      /* 1 means stdout */
    movl $hello, %ecx  /* address of hello */
    movl $14, %edx     /* len of string */
    int  $0x80         /* trap: execute syscall */

    movl $1, %eax      /* syscall #1 is _exit() */
    movl $0, %ebx      /* exit status: 0 */
    int  $0x80         /* trap */

Übersetzen und ausführen:

$ as -o hello.o hello.s
$ ld -o hello hello.o
$ ./hello 
Hello, world!

Du kannst, wenn du das willst, auch die Intel-Syntax statt der beim GAS üblichen AT&T-Syntax benutzen. Dazu muss dein Quellcode hiermit beginnen:

.intel_syntax noprefix

Ich würde mich auch freuen, hier von anderen Usern coole Links zu sehen, denn meine Assembler-Linksammlung ist quasi nichtexistent. Hier sind meine eigenen Notizen zu dem Thema:

http://www.uninformativ.de/?section=tags&which=assembler

Erinnert mich daran, dass ich mal was zur Benutzung vom gdb-Debugger aufschreiben wollte …

Sonstiges:

YEPHENAS

Anmeldungsdatum:
8. Juni 2009

Beiträge: 352

infty999 schrieb:

Hallo Leute, ich habe heute angefangen mir mal Assembler anzuschauen und ich musste glücklicherweise feststellen, dass das schon in Ubuntu mit drin ist. Welch ein Glück. Allerdings bin ich in dem zusammenhang über gcc und as als Assembler gestolpert. Gibt es dabei Unterschiede? Und eventuell Webseiten wo ich als Referenz alles wichtige finde um die notwendigen Anpassungen durchzuführen, sofern meine Tutorials nicht mit den Assemblern konform sind? Fände ich toll.

gcc leitet Assembler-Sourcen doch letztlich nur an as (also GNU as) weiter, also kommt es aufs gleiche raus.

Eine wirkliche Alternative wäre NASM.

TraumFlug

Avatar von TraumFlug

Anmeldungsdatum:
16. Juli 2009

Beiträge: 999

Wohnort: zwischen den ohren

Hmmm, Assembler-KnowHow wird heutzutage eigentlich nur in wenigen Fällen angewendet.Die da wären:

  • Man muss irgendeine Routine heftigster optimieren als der C-Compiler es kann (nach grösse oder ausführungsgeschwindigkeit)

  • Man braucht Zugriff auf bestimmte Systemfunktionen (hardware-register, bestimmte spezialrechenoperationen, die man mit c nicht so hinbekommt, wie man will...), die man nur lowest-level erreichen kann (da der Compiler bestimmte sachen nicht beherrscht, meist inline-makros, die dann in high-level code aufgerufen werden)

  • "böse": man will ein Programm, zu dem man keinen Quellcode hat, mühsam analysieren 🐸

  • "noch böser" man muss ein exploit-payload für irgendeinen buffer-overflow erzeugen

  • man hat einfach spass am basteln/frickeln, und das geht richtig gut ab! 😈

beachte, das es mehrere Syntaxformen für assembler gibt, z.B. bei x86 den at&t und intel syntax. ich weiss nicht, wie's z.B. bei arm ist. bei x86 kann man beispielsweise ein .c(++) Programm mit gcc mit der Option "-S" (statt "-o" oder "-c") in lesbaren assembler umsetzen lassen (nicht erschrecken, was der Compiler macht ist hirn****!), mit Zusatzoption "-masm=intel" / "-masm=att" kriegst schonmal 'nen Unterschied zwischen at&t und intel syntax mit (at&t ist standard bei gas, intel bei nasm, bei beiden kann man glaube ich wählen, und beide sind in bestimmten details dann trotzdem unterschiedlich). Mit "-fverbose-asm" packt der Compiler noch'n par (noch hirnge****tere!!!) Kommentare zum "besseren verständnis" dazu. Beachte auch, sämtliche Optimierungen ala "-Ox" und "mtune=" sieht man dann im assembler (ist oft interessant).

Zum Anfang, nach ein paar generischen Tutorials, würde ich dir also empfehlen, eine gute Tabelle der Assemblerbefehle für deine Architektur aufzutreiben, und kleine (erstmal) C Programme von gcc nach asm zu übersetzen und allerlei drin zu studieren. wenn du alles verstehst, was der compiler macht (ist wiegesagt im Vergleich zu gutem handgeschriebenen oft hirnge****t), kannst versuchen selber sowas zu hacken. Viel Spass! ☺

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2503

infty999

(Themenstarter)

Anmeldungsdatum:
27. Mai 2012

Beiträge: Zähle...

Hey, cool danke, das wird mir auf jeden Fall alles sehr helfen. Besonders interessant finde ich Inline Assembler. Kann es irgendwie sein, dass Assembler zu unrecht für viel zu kompliziert gehalten wird? Das HelloWorld Programm fand ich sogar recht verständlich, oder kommt mir das nur so vor?

Gruß

Infty

jakon Team-Icon

Lokalisierungsteam

Anmeldungsdatum:
16. November 2009

Beiträge: 419

Wenn du „Hello world“ in Assembler mit echo Hello world! in sh vergleichst, dann wirst du schon sehen, warum es für kompliziert gehalten wird.

Und „Hello world“ ist ja nun wirklich nicht das komplizierteste Programm … Schleifen, etc. sind dann noch mal schwerer. Aber im Großen und Ganzen ist das schon zu meistern.

stfischr Team-Icon

Avatar von stfischr

Anmeldungsdatum:
1. März 2007

Beiträge: 19197

Hi.

infty999 schrieb:

Hey, cool danke, das wird mir auf jeden Fall alles sehr helfen. Besonders interessant finde ich Inline Assembler. Kann es irgendwie sein, dass Assembler zu unrecht für viel zu kompliziert gehalten wird? Das HelloWorld Programm fand ich sogar recht verständlich, oder kommt mir das nur so vor?

Assembler an sich ist super einfach. Wenige Grundlegende Befehle, Flussteuerungen und ein paar Register. Das schwierige ist es damit Programme zu schreiben, die schneller sind als das was man vom GCC bekommt. Dazu sind nämlich umfassende Kenntnisse über diverse Architekturen und Funktionsweisen von Computern im Allgemeinen notwendig.

TraumFlug

Avatar von TraumFlug

Anmeldungsdatum:
16. Juli 2009

Beiträge: 999

Wohnort: zwischen den ohren

Einen Punkt hatte ich noch vergessen: Asm kann auch ungemein helfen, schwierige Fehler bei highlevel-Compilersprachen zu debuggen. Oder Macken im Compiler selbst...

Und du hast recht, Assembler von der Struktur her an sich ist eher "simpel" - nur man muss eben sehr viel "im Kopf" behalten, was einem sonst die Compiler und die Sprachstruktur abnehmen. Wenn man etwa eine Asm-Routine geschrieben hat, und nach einem halben Jahr wieder ankuckt...wenn sie nicht wirklich super kommentiert ist, viel Spass - bei C steigt man noch schnell wieder durch, bei Assembler muss man erstmal mühsam alles nachvollziehen. Erst recht, wenn sie handoptimiert wurde, denn dann hält man sich ja eher nicht an übersichtliche Gruppierung der Befehle, sondern mischt Stränge für "parallelität" und dergleichen 😈

Aber das es so "verteufelt" wird, finde ich auch falsch, grade für C(++) Programmierer ist eine kleine Asm-Lektion eine super Ergänzung für's Nähkästchen. Weil sie dabei lernen können, was mit ihrem Code nach dem Compilieren genau Passiert, wie der Compiler bestimmte sachen auf der Hardware umsetzt, und wie der code dann auf der Maschine läuft. Und warum manche "elegante" Lösungen eben viel langsamer sind als andere, "nicht so elegante".

Inline-Assembler ist eine gute Idee, weil man so erstmal das ganze "drumherum" mit Startbibliothek und "calling conventions" ausser Acht lassen, und sich auf kleine Algorithmenbausteine konzentrieren kann. Ich hatte vor Jahren meine ersten Experimente allerdings mit einem C Programm, das Routinen, die aus reinem Asm bestanden, eingebunden hat (seperates objekt, eingelinkt). Man muss sich halt um den Stack und Speicheraddressen von Werten kümmern, aber ich fand Inline, grade bei gcc, eher "abschreckend komplizierter"...weiss jetzt auch nicht warum, aber musst du mal sehen...

Antworten |