TI2/Rechnerarchitektur-Tutorium, 09./10.06.2015

Nutzung der Floating-Point-Unit (FPU)

Für die Aufgabe 3 vom 8. Übungsblatt sollen IEEE-Gleitkommazahlen addiert beziehungsweise subtrahiert werden. Anfangs gab es dazu x87-Coprozessoren (x87 bezeichnet den Teil des x86-Befehlssatzes, mit dem Gleitkommaberechnungen durchgeführt werden), die mit einer Art Stack-Architektur arbeiteten. Heute ist jedoch x87 eher unwichtig geworden, da heutige Prozessoren die Gleitkommaberechnungen über SSE2 durchführen – SSE2 ist bei allen x86-64bit-Prozessoren vorhanden.

Parameterübergabe und verwendetet Register

Anders als bei Ganzzahlen können für IEEE-Gleitkommazahlen nicht die Standard-Register rax, rbx, etc. verwendet werden. Dafür gibt es spezielle Register, die mit xmm0, xmm1, …, xmm15 bezeichnet werden.

In der Calling Convention kann man lesen, dass Gleitkommazahlen über die Register xmm0, xmm1, etc. in dieser Reihenfolge übergeben werden. Wichtig ist, dass bei gemischten Ganz- und Gleitkommazahlen die Register pro Typ in der Reihenfolge verwendet werden. Der Aufruf test(1, 1.2, 4, 5, 6.3, 2.3) übergibt die Zahlen in den folgenden Registern:

rdi = 1,             rsi  = 4, rdx  = 5,
         xmm0 = 1.2,                     xmm1 = 6.3, xmm2 = 2.3

Genauso passiert die Rückgabe einer Gleitkommazahl über das ersten SSE-Register xmm0.

Funktionen zum Rechnen

Um beispielsweise zwei Zahlen zu multiplizieren gibt es (unter anderem) die folgenden zwei Befehle:

mulss xmm2, xmm4 // xmm2 = xmm2 * xmm4 // (32bit)
mulsd xmm5, xmm1 // xmm5 = xmm5 * xmm1 // (64bit)

Der Unterschied besteht darin, dass die ss-Befehle für single precision, also 32bit-IEEE-Gleitkommazahlen funktionieren, während die sd-Befehle für double precision, also 64bit-IEEE-Gleitkommazahlen funktionieren. Hier muss also aufgepasst werden, ob die Funktion float (32bit) oder double (64bit) Parameter erwartet.

Analog dazu gibt es noch weitere Funktionen wie addss, addsd, subss, subsd, etc.