Assembler auf 64Bit System



  • Hallo,
    ich habe bisher Assembler auf meinem 32Bit Ubuntu benutzt.

    bsp folgendes Programm:

    .data
    	intout: .string "Fakultat: %d\n"
    	n:	.long 12
    	i:	.long 2
    
    .globl main
    
    main:
    
    movl $1,%eax
    movl i,%ebx
    
    .L1:
    cmpl n,%ebx
    jg .ende
    imull %ebx,%eax
    addl $1,%ebx
    jmp .L1
    
    .ende:
    
    pushl %eax
    pushl $intout
    call printf
    
    movl $1,%eax
    int $0x80
    

    das ganze hab ich ausführbar machen können mit:

    yasm -f elf -p gas fakultat.asm
    gcc -o fakultat fakultat.o

    Wenn ich das aber nun auf einem 64Bit Ubuntu versuche dann bekomme ich diesen Fehler:

    nach gcc -o fakultat fakultat.o
    /usr/bin/ld: i386 architecture of input file `fakultat.o' is incompatible with i386:x86-64 output
    collect2: ld returned 1 exit status

    Ich wüsste nun gerne, was ich ändern muss, damit ich wieder ein ausführbares Programm bekomme?

    Soweit ich weiß muss ich die Registernamen ändern in %rax und %rbx aber dann bekomme ich nur noch mehr Fehlermeldungen.



  • Du musst dich erstmal entscheiden ob du eine 32 oder eine 64 Bit Anwendungen erzeugen willst. Auf einem 64 Bit System läuft in der Regel beides, mischen geht aber nicht. Dementsprechend musst du yasm mit "-f elf -m amd64" (oder kürzer "-f elf64") dazu veranlassen 64 Bit Objektfiles zu erzeugen, oder gcc mit "-m32" dazu zu bringen eine 32 Bit Executable zu erstellen.



  • So erst mal danke für die schnelle Antwort.

    Okay, ich geh mal davon aus, dass ich wenn ich eine 32 Bit Executable erstellen möchte, kann ich den Code so lassen wie er ist, das ist dann zunächst mal die einfachere Variante. Die andere werde ich später noch versuchen.

    Wenn ich das also richtig verstanden habe reicht mir nun

    gcc -m32 -o fakultat fakultat.o

    darauf bekomme ich jetzt folgende Ausgabe:
    /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.3/libgcc.a when searching for -lgcc
    /usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.3/libgcc.a when searching for -lgcc
    /usr/bin/ld: cannot find -lgcc
    collect2: ld returned 1 exit status

    Wenn ich das richtig verstanden habe dann fehlt mir da irgendwas oder?

    Edit: Also ich glaube dieses irgendwas ist eine Bibliothek im Verzeichnis /usr/lib/gcc/x86_64-linux-gnu/4.4.3 leider hab ich keine Ahnung wie ich die da rein bekomme.



  • Der gcc braucht zum Linken einer 32 Bit Executable dann natürlich auch die 32 Bit Version der gcc lib. Die sind wenn ich mich nicht irre bei Ubuntu im Paket lib32gcc1.



  • Die lib32gcc1 ist bei mir installiert, bringt leider nichts.

    Ich denke ich werde morgen mal die andere Variante versuchen mit den 64 Bit Objektfiles.



  • Zur Not kann man ja erstmal

    as proggi.s -o proggi.o
    und dann
    ld proggi.o -o proggi machen

    ich hatte mal die genau umgekehrt Meldung als ich fasm auf dem 64bit system mit
    gcc compilieren wollte - nix 32bit out...nagut, dann eben nich 😉



  • Hier mal ein zwischenbericht von meinen Experimenten:

    Ich habe versucht

    yasm -f elf -m amd64 -p gas fakultat.asm
    und
    yasm -f elf64 -p gas fakultat.asm

    beide male mit dem Ergebnis:
    fakultat.asm:23: error: invalid combination of opcode and operands
    fakultat.asm:24: error: invalid combination of opcode and operands

    also ein Problem mit der Ausgabe, nachdem ich diese auskommentiert habe hat es funktioniert. Bringt ja aber nix, weil ich dann keine ausgabe habe.

    Daraufhin habe ich mir gedacht, es könnte ja am pushl Befehl liegen und habe folgendes versucht: (siehe Zeile 14 und 15)

    .data
    	intout: .string "Fakultat: %d\n"
    	n:	.long 12
    	i:	.long 2
    
    .globl main
    
    main:
    
    movl $1,%eax
    movl i,%ebx
    
    pushl %eax
    popl %eax
    
    .L1:
    cmpl n,%ebx
    jg .ende
    imull %ebx,%eax
    addl $1,%ebx
    jmp .L1
    
    .ende:
    
    #pushl %eax
    #pushl $intout
    #call printf
    
    movl $1,%eax
    int $0x80
    

    habe auch hier wieder

    yasm -f elf64 -p gas fakultat.asm

    versucht mit folgendem Fehler:
    fakultat.asm:15: error: `popl' invalid in 64-bit mode

    also hier hat der push Befehl wohl funktioniert, also habe ich dann nur die Zeile mit dem popl %eax entfernt und erneut versucht mit dem Ergebnis

    fakultat.asm:14: error: invalid combination of opcode and operands

    also der push Befehl funktioniert wieder nicht.

    Leider werde ich da nicht schlau draus.

    Dann habe ich wieder das Ursprüngliche Programm genommen und habe es nach dem Vorschlag von nachtfeuer mit
    as fakultat.asm -o fakultat.o
    versucht.

    Ergebnis:
    fakultat.asm: Assembler messages:
    fakultat.asm:23: Error: suffix or operands invalid for push' fakultat.asm:24: Error: suffix or operands invalid forpush'



  • "pushl" und "popl" ist eigentlich quatsch, da sowieso nur eine Standardgröße auf dem Stack copiert wird, d.h. auf x86_64 sinds immer 8 Bytes.
    push rax wäre so gesehen sinnvoll.

    aber wieso hast du z.B.

    push eax
    pop  eax
    

    im Code stehen?

    Und wenn ich vielleicht noch eine Frage stellen dürfte:
    hast du eventuell noch irgendwo einen Windows Pc oder eine Dosdiskette (+Diskettenlaufwerk dafür)?



  • aber wieso hast du z.B.
    Assembler Code:
    push eax
    pop eax

    Das habe ich nur testweise mal da rein geschrieben.

    hast du eventuell noch irgendwo einen Windows Pc oder eine Dosdiskette (+Diskettenlaufwerk dafür)?

    Zurzeit hab ich nur Linux am laufen. Hab aber noch ein PC mit Diskettenlaufwerk und Disketten für DOS 6.22. Warum?

    Mir gehts es ja darum das Programm auf einem 64Bit System zum laufen zu bringen. Wie ich bereits in meinem ersten beitrag hierzu geschrieben habe läuft das ja auf 32Bit.
    Sieh es als kleines Experiment nebenbei.



  • Florian327 schrieb:

    Zurzeit hab ich nur Linux am laufen. Hab aber noch ein PC mit Diskettenlaufwerk und Disketten für DOS 6.22. Warum?

    Weil das alte Dos und die Debugger dafür eine sehr viel besser Einstiegsmöglichkeit in Assembler bieten. In Linux und in C geht es immer auch um Portabilität der Programme. Das sind keine Assemblerfreundlichen Voraussetzungen, und das wirkt sich auch auf die Tools aus, die zur Verfügung stehen
    (oder das Know How rund um Hardware und hardwarenahe Programmierung).
    Eines der besten Linux Programme ist ein geklontes altes Dos-Programm - Einsteigerfreundlich wie Profifreundlich: der Midnight Commander. Das Dos-Original von Peter Norton wurde, glaube ich, damals sogar in Asm gecoded)
    (man kann sich also witzigerweise auf einen alten Dos und dem Norton Tool einen Eindruck von modernen Linux verschaffen 😉

    Spaß beiseite: 64bit Linux/Unix Asm macht schon Spaß, aber lieber vom Einfachen zum Schweren. 64bit Linux/Unix Asm ist nicht von sich aus schwierig, die Einsteigerfeindlichkeit und so manches Problem der Unixe machts schwierig.



  • Spaß beiseite: 64bit Linux/Unix Asm macht schon Spaß, aber lieber vom Einfachen zum Schweren. 64bit Linux/Unix Asm ist nicht von sich aus schwierig, die Einsteigerfeindlichkeit und so manches Problem der Unixe machts schwierig.

    Aber genau zum 64bit Linux/Unix Asm will ich doch hin. Ich habe ja schon das ein oder andere Assemblerprogramm geschrieben, also habe ich mir ein ganz einfaches davon rausgesucht (fakultat.asm).

    Ich hatte mir erhofft schrittweise zum 64bit zu kommen indem ich erst mal meine alten Programme wieder zum laufen bringe.

    Anscheinend ist ja schon das erste davon ein Reinfall.

    Was bleiben mir also noch für Möglichkeiten? In Form von einem Buch oder sonstigem Tutorial habe ich leider nichts brauchbares zum X86-64 instruction set gefunden.



  • Die beste Quelle sind die Hersteller selbst - die Dokumentationen sind aber natürlich im Intel-Syntax verfasst.
    AMD
    Intel



  • naja, der Unterschied ist nicht allzugroß, man hat ein paar mehr Register die sich ziemlich genauso verhalten wie die 16bit Register, von Xmms und Co mal abgesehen, aber auch die...was viele nicht schnallen, man kann ja auch 128bit programming auf 32bit oder 16bit Systemen betreiben.

    Aber ein paar Hinweise gibt es schon, hier z.B.
    http://www.flatassembler.net/
    http://www.agner.org/
    http://www.complang.tuwien.ac.at/ubvl/amd64/amd64h.html
    http://www.x86-64.org/
    http://en.wikipedia.org/wiki/X86-64
    http://de.wikipedia.org/wiki/AMD64
    http://developer.amd.com/Pages/default.aspx
    http://www.intel.com/products/processor/manuals/
    usw.
    und meist auch irgendwie im Linuxsystem selbst...;)



  • Hallo,
    also es hat wieder Fortschritte gegeben.

    mir fehlte unter Ubuntu noch die Bibliothek: gcc-multilib

    hab ich jetzt nachinstalliert und siehe da mit

    yasm -f elf -p gas fakultat.asm
    gcc -o fakultat -m32 -mtune=i386 fakultat.o

    und einer kleinen Korrektur im Code

    .data
    intout:	.string "Fakultaet: %d\n"
    n:		.long 12
    
    .globl main
    
    .L1:
    imull %ebx, %eax
    addl $1, %ebx
    jmp .L2
    
    main:
    movl $1, %eax
    movl $2, %ebx
    .L2:
    cmpl n, %ebx
    jle .L1
    
    pushl %eax
    pushl $intout
    call printf
    
    movl $1, %eax
    int $0x80
    

    ist mein Programm jetzt ausführbar.

    Noch mal Danke an alle.


Anmelden zum Antworten