H. Högl, 6. Dezember 2018
Ergänzung im Fach Systemnahe Programmierung (http://hhoegl.informatik.hs-augsburg.de/hhwiki/SysProg)
Inhalt
Einige Befehlsnamen haben nun ein "q" angehängt. Das "q" steht für "Quadword", was 64-Bit bedeutet (Erinnerung: Bei Intel ist ein "Word" 16-Bit breit). Beispiele:
movq $1, 16(%rsp).
Assembler Direktive .quad
.data count: .quad 0
Argumente werden nicht mehr auf dem Stack übergeben, sondern in Registern: rdi, rsi, rdx, rcx, r8, r9. Gleitkommazahlen (float, double) werden in den Registern xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 übergeben.
Alle weiteren Argumente werden auf dem Stack übergeben in der Reihenfolge von rechts nach links.
Der Stack-Pointer muss vor dem Aufruf einer Funktion auf eine 16-Byte Grenze gesetzt werden. Direkt nach dem Aufruf der Funktion mit call ist die Return-Adresse (8 Byte) auf dem Stack, so dass der Stack innerhalb der Funktion wieder auf eine 16-Byte Grenze gesetzt werden muss.
Die aufgerufene Funktion muss folgende Register erhalten: rbp, rbx, r12, r13, r14, r15 ("callee-save registers").
Rückgabewerte von Funktionen sind in rax oder rdx:rax. Bei einem Gleitkommawert ist es xmm0 oder xmm1:xmm0.
Beispiele:
Bei 64-Bit Linux haben die Systemaufrufe andere Nummern als bei 32-Bit! Eine Tabelle mit den 64-Bit Systemaufrufen findet man z.B. unter: https://filippo.io/linux-syscall-table/ oder http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/.
Der Systemaufruf wird mit dem neuen syscall Maschinenbefehl gemacht, nicht wie bei 32-Bit mit int $0x80.
Beispiel
GNU Assembler
Programme in [BH]
Programme in [RAY]
Let's Write Some X86-64
http://nickdesaulniers.github.io/blog/2014/04/18/lets-write-some-x86-64/
Intel Syntax / Nasm / Yasm
(Programme in der Intel Syntax kann man entweder mit nasm oder yasm übersetzten. Die Kommandozeile für nasm und yasm lauten etwa so:
nasm -f elf64 -l demo.lst demo.s yasm -m amd64 --list=demo.lst -f elf -gstabs -D ELF_TYPE demo.s
[RAY] Ray Toal, GNU Assembler Examples
http://cs.lmu.edu/~ray/notes/gasexamples/
Ein sehr guter und knapper Text, der das wesentliche der x86-64 Assembler Programmierung mit dem GNU Assembler vermittelt. Ausgedruckt ist er ca. 10 Seiten lang. Er enthält neben den Beispielen, die ich übernommen habe, auch kurze Beispiele für Data-Section, lokale Variable, Stack Frames, Sättigungsarithmetik, SIMD Parallelität, Rekursion und Gleitkommazahlen.
Hinweis zum Kompilieren: Die Programme, die gegen die libc linken, müssen noch die gcc Option -no-pie erhalten, sonst kompilieren sie nicht.
[BH] Bryant, Hallaron, x86-64 Machine-Level Programming, 2005 (asm64-handout.pdf)
Dieser Text ist 46 Seiten lang und enthält viele Beispiele in GNU Assembler. Er ist detaillierter als [RAY]. Es sind auch viele Übungsaufgaben eingestreut, an denen man sich versuchen kann.
Syntax, Register und Adressierungsarten im 64-Bit Modus (sehr kurz).
https://www.engr.mun.ca/~anderson/teaching/8894/reference/x86-assembly/
Der Text stammt von folgender längerer Vorlage ab: Prof. Douglas Thain, Introduction to X86-64 Assembly for Compiler Writers, https://www3.nd.edu/~dthain/courses/cse40243/fall2015/intel-intro.html
Linux System Calls
https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls.html
Intel IA-64 Manuals
Ed Jorgensen, x86-64 Assembly Language Programming with Ubuntu, Version 1.1.14, September 2018
# GNU Assembler im 64-Bit Modus as -g -al=hello.lst -o hello.o hello.s # Mit dem GCC eine .s Datei kompilieren im 64-Bit Modus gcc -c hello.s # Mit dem GCC einen C Quelltext im 32-Bit Modus nach Assembler wandeln. # Es wird die Datei code.s erzeugt. gcc -O2 -S -m32 code.c # Mit dem GCC einen C Quelltext im 64-Bit Modus nach Assembler wandeln. # Es wird die Datei code.s erzeugt. gcc -O2 -S -m64 code.c # Mit dem GNU Linker ld eine oder mehrere .o Dateien zu einer # ausfuehrbaren Datei linken. Weiter .o Dateien gibt man einfach am # Ende der Kommandozeile an. ld -o hello hello.o