[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, r151 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 | |
foojonas@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