[TI2]
in den E-Mail-Betreff schreibenKoordination des Übungsbetriebs: Simon Schmitt (simon.schmitt [Klammeraffe] fu-berlin.de)
rax, rbc, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, r14, r15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
(Beispiel aus der Vorlesungsfolie.)
1 2 3 4 5 6 |
|
Kompiliert mit gcc -o hello hello.c
sieht der Teil der main
-Methode so aus:
ba0e000000bef4054000bf01000000
e8c2feffffbf00000000e8a8feffff
Man kann das Programm auch wieder disassemblieren (mit objdump -M intel-mnemonic -d hello
). Der Teil der main
-Methode sieht dann folgendermaßen aus:
1 2 3 4 5 6 |
|
Zum Testen, ob nasm funktioniert könnt ihr diese Zip-Datei runterladen:
jonas@arch ~ti2t % wget https://page.mi.fu-berlin.de/jonascleve/data/download/nasm_test.zip
jonas@arch ~ti2t % unzip nasm_test.zip
Archive: nasm_test.zip
creating: nasm_test/
inflating: nasm_test/hello.asm
inflating: nasm_test/bar.c
inflating: nasm_test/foo.asm
inflating: nasm_test/Makefile
jonas@arch ~ti2t % cd nasm_test
jonas@arch ~ti2t/nasm_test % make all
nasm -f elf64 foo.asm
gcc -o foo foo.o
nasm -f elf64 hello.asm
gcc -o hello hello.o bar.c
jonas@arch ~ti2t/nasm_test % ./foo
Hello, world!
jonas@arch ~ti2t/nasm_test % ./hello
Test Here!
Hello from Assembly!
Wir wollen eine kleines Programm schreiben, dass drei Ganzzahlen entgegennimmt und von der Summe der ersten beiden die letzte Zahl abzieht. Also f(a, b, c)=a + b − c.
Wir schreiben ein C-Programm, dass unsere später in Assembler geschrieben Funktion aufruft und das Ergebnis ausgibt.
bar.c:
1 2 3 4 5 6 7 8 9 10 |
|
Bei Ausführung sollte i hat den Wert: -668 herauskommen.
Eine erste Assembler-Funktion, die nicht macht, was wir wollen, aber wir können es zumindestens ausführen.
foo.asm:
1 2 3 4 |
|
foo
jonas@arch ~ti2t % nasm -f elf64 foo.asm
jonas@arch ~ti2t % gcc -o run foo.o bar.c
jonas@arch ~ti2t % ./run
i hat den Wert: 4195601
Woher kommt der Wert für i
? Lösung: Calling Conventions
“The first six integer […] arguments are passed in registers RDI
, RSI
, RDX
, RCX
, R8
, and R9
[…] and the return value is stored in RAX
.”
Wir wollen erstmal einen festen Wert zurückgeben:
1 2 3 4 5 |
|
jonas@arch ~ti2t % nasm -f elf64 foo.asm
jonas@arch ~ti2t % gcc -o run foo.o bar.c
jonas@arch ~ti2t % ./run
i hat den Wert: 1234
Mit dem Wissen, was in welchem Register steht können wir nun auch die komplette Funktion implementieren:
1 2 3 4 5 6 7 |
|
jonas@arch ~ti2t % nasm -f elf64 foo.asm
jonas@arch ~ti2t % gcc -o run foo.o bar.c
jonas@arch ~ti2t % ./run
i hat den Wert: -668