529 lines
11 KiB
NASM
529 lines
11 KiB
NASM
.data
|
|
fltout: .string "Wert: %f\n"
|
|
intout: .string "Wert: %d\n"
|
|
a: .float 2.76
|
|
b: .float -3.12
|
|
c: .float 1.2
|
|
|
|
.text
|
|
|
|
#Windebugging
|
|
.globl _main
|
|
.globl main
|
|
#.global printf
|
|
#printf:
|
|
# call _printf
|
|
# ret
|
|
_main:
|
|
jmp main
|
|
main:
|
|
|
|
#float 2 console
|
|
movl a, %eax
|
|
call fltprint
|
|
|
|
# a * b = -8,6112
|
|
#movl a, %eax
|
|
#movl b, %ebx
|
|
#call fltmul
|
|
#call fltprint
|
|
|
|
# b + c = -1,92
|
|
movl b, %eax
|
|
movl c, %ebx
|
|
call fltadd
|
|
call fltprint
|
|
|
|
|
|
# c + a = 3,96
|
|
#movl c, %eax
|
|
#movl a, %ebx
|
|
#call fltadd
|
|
#call fltprint
|
|
|
|
|
|
.ende:
|
|
# Exit
|
|
movl $1, %eax
|
|
int $0x80
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
/*
|
|
Addition zweier float Werte
|
|
Eingabe: %eax, %ebx
|
|
Ausgabe: %eax
|
|
|
|
Notizen: --AUSFUELLEN--
|
|
*/
|
|
fltadd:
|
|
pushl %eax
|
|
pushl %ebx
|
|
|
|
|
|
|
|
|
|
# VERGLEICHE EXPONENTEN -> SHIFTE MANTISSE ENTSPRECHEND
|
|
##################################################################################
|
|
|
|
call exponent # liefert exponent von %eax in %eax #lieft null -> für 3.... -> 11...., also müsste exponent mind 1 sein
|
|
pushl %eax # movl %eax, %edx # a
|
|
# b
|
|
# exp a
|
|
|
|
movl 4(%esp), %eax # movl %ebx, %eax # verschieben b in %eax
|
|
call exponent # liefert exponent von %ebx in %eax #ist null und richtig
|
|
pushl %eax # # a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
|
|
movl %eax, %ebx # Eponent von %ebx in %ebx
|
|
movl 4(%esp), %eax # Exponent von %eax in %eax
|
|
|
|
|
|
cmp %ebx, %eax # vergleiche exponenten
|
|
jb .shift_eax # %ebx ist größer -> shift eax
|
|
ja .shift_ebx # %ebx ist kleiner -> shift ebx
|
|
je .shift_nothing # exponenten gleich, kein shift notwendig
|
|
|
|
|
|
.shift_eax:
|
|
|
|
#TODO
|
|
pushl %ebp
|
|
movl %esp, %ebp
|
|
|
|
pushl %ebx # Exponent sichern
|
|
subl %ebx, %eax # %eax - %ebx
|
|
pushl %eax # Shiftwert sichern
|
|
movl 4(%ebp), %ebx # Urpsüngliche Gleitkommazahl herstellen
|
|
movl 8(%ebp), %eax
|
|
call significand # liefert Mantisse von %eax
|
|
|
|
popl %ecx
|
|
|
|
.loop_shift: # Shifte Mantisse von %eax x-mal
|
|
shrl $1, %eax
|
|
loop .loop_shift
|
|
|
|
pushl %eax
|
|
movl %ebx, %eax
|
|
call significand # Extrahiere Mantisse von %ebx
|
|
movl %eax, %ebx
|
|
popl %eax
|
|
popl %edx # Exponent wiederherstellen
|
|
jmp .add_fraction
|
|
|
|
popl %ebp
|
|
jmp .shift_nothing
|
|
|
|
|
|
.shift_ebx:
|
|
|
|
subl %ebx, %eax # %eax - %ebx
|
|
pushl %eax # Shiftwert sichern # a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# shift b
|
|
movl 12(%esp), %eax # Urpsüngliche Gleitkommazahl herstellen (b)
|
|
call significand # liefert Mantisse von b
|
|
|
|
popl %ecx
|
|
|
|
.loop_shift2: # Shifte Mantisse von %eax x-mal um 2 nach LINKS
|
|
shll $1, %eax
|
|
loop .loop_shift2
|
|
|
|
pushl %eax # a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
movl 16(%esp), %eax
|
|
call significand # Extrahiere Mantisse von a
|
|
pushl %eax # a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
|
|
jmp .check_sign
|
|
|
|
.shift_nothing: # %eax und %ebx haben gleichen Exponenten!
|
|
movl 8(%esp), %eax
|
|
call significand # Extrahiere Mantisse von b
|
|
pushl %eax
|
|
movl 16(%esp), %eax
|
|
call significand # Extrahiere Mantisse von a
|
|
pushl %eax
|
|
#######################################################################################
|
|
|
|
|
|
;# VERGLEICHE VORZEICHEN UND BILDE EVENTUELL ZWEIERKOMPLEMENT
|
|
#######################################################################################
|
|
|
|
.check_sign:
|
|
|
|
# a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
|
|
movl 20(%esp), %eax # Urpsüngliche Gleitkommazahl herstellen (a)
|
|
call sign # Vorzeichen von %eax extrahieren (a)
|
|
cmp $1, %eax
|
|
je .build_complement_a # Zweier Komplement bilden
|
|
|
|
.sign_b:
|
|
movl 16(%esp), %eax # Urpsüngliche Gleitkommazahl herstellen (b)
|
|
call sign # Vorzeichen von %eax extrahieren (b)
|
|
cmp $1, %eax
|
|
je .build_complement_b # Zweier Komplement bilden
|
|
jmp .sign_end
|
|
|
|
.build_complement_a:
|
|
movl (%esp), %eax # Hole Mantisse von a
|
|
xor $0x007FFFF, %eax # Invertiere %eax 0000 0000 07 F F F F F
|
|
inc %eax # %eax +1
|
|
movl %eax, (%esp) # Schriebe Mantisse zurück
|
|
jmp .sign_b
|
|
|
|
.build_complement_b:
|
|
movl 4(%esp), %eax # Hole Mantisse von b
|
|
xor $0x007FFFF, %eax # Invertiere %eax
|
|
inc %eax # %eax + 1
|
|
movl %eax, 4(%esp) # Schreibe Mantisse zurück
|
|
jmp .sign_end
|
|
|
|
.sign_end:
|
|
|
|
|
|
#######################################################################################
|
|
|
|
|
|
;# ADDIERE MANTISSEN
|
|
#######################################################################################
|
|
.add_fraction:
|
|
|
|
# a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
|
|
movl (%esp), %eax # mantisse a
|
|
movl 4(%esp), %ebx # mantisse b
|
|
addl %ebx, %eax # Mantissen addieren
|
|
pushl %eax # %eax sichern # a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
# new mantisse
|
|
|
|
|
|
movl 16(%esp), %eax # exp a
|
|
movl 12(%esp), %ebx # exp b
|
|
|
|
subl %ebx, %eax # exp a - exp b
|
|
cmp $0, %eax # exp a - exp b = 0?
|
|
je .exp_eql
|
|
ja .exp_a_big
|
|
jb .exp_b_big
|
|
|
|
.exp_eql:
|
|
movl 16(%esp), %eax # exp a
|
|
pushl %eax
|
|
movl 28(%esp), %eax # a
|
|
call sign
|
|
pushl %eax
|
|
# a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
# new mantisse
|
|
# new exp
|
|
# new sign
|
|
jmp .build_flt
|
|
|
|
.exp_a_big:
|
|
movl 16(%esp), %eax # exp a
|
|
pushl %eax
|
|
movl 28(%esp), %eax # a
|
|
call sign
|
|
pushl %eax
|
|
|
|
# a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
# new mantisse
|
|
# new exp
|
|
# new sign
|
|
jmp .build_flt
|
|
.exp_b_big:
|
|
movl 12(%esp), %eax # exp b
|
|
pushl %eax
|
|
movl 24(%esp), %eax # b
|
|
call sign
|
|
pushl %eax
|
|
|
|
# a
|
|
# b
|
|
# exp a
|
|
# exp b
|
|
# mantisse b
|
|
# mantisse a
|
|
# new mantisse
|
|
# new exp
|
|
# new sign
|
|
jmp .build_flt
|
|
|
|
.build_flt:
|
|
|
|
movl (%esp), %eax # sign << 31
|
|
movl 4(%esp), %ebx # exp << 23
|
|
movl 8(%esp), %ecx # mantisse << 0
|
|
shll $31, %eax # ok!
|
|
shll $23, %ebx # ok!
|
|
|
|
orl %ebx, %eax
|
|
orl %ecx, %eax
|
|
|
|
addl $36, %esp
|
|
|
|
#??????????????????????????????ß
|
|
#andl $0x00800000, %eax # prüfe ob shift und Exponentanpassung nötig ist
|
|
#shrl $23, %eax
|
|
#cmp $0, %eax
|
|
#je .no_shift
|
|
|
|
|
|
#popl %eax
|
|
#shrl $1, %eax
|
|
#inc %edx
|
|
|
|
|
|
#.no_shift:
|
|
|
|
|
|
## Vorzeichenbit muss noch behandelt werden
|
|
# cmp $0, %eax # ergebnis < 0 -> Zweierkomplement bilden
|
|
# ja .no_complement
|
|
#
|
|
# # Zweierkomplement vom Ergebnis bilden
|
|
# xor $0x00711111, %eax
|
|
# inc %eax
|
|
# xor $0x80000000, %eax # -> Vorzeichenbit setzen
|
|
#
|
|
# .no_complement:
|
|
#
|
|
|
|
|
|
# # Zahl wieder "zusammenbauen"
|
|
# subl $896, %edx # Exponent wieder in richtige Form bringen
|
|
# andl 0x7F800000, %edx
|
|
|
|
# orl %edx, %eax # Exponent_Mantisse
|
|
|
|
|
|
|
|
#######################################################################################
|
|
ret
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
################################################################################################################################
|
|
|
|
/*
|
|
Multiplikation zweier float Werte
|
|
Eingabe: %eax, %ebx
|
|
Ausgabe: %eax
|
|
|
|
Notizen: --AUSFUELLEN--
|
|
*/
|
|
fltmul:
|
|
|
|
pushl %eax
|
|
pushl %ebx
|
|
|
|
|
|
call significand # Mantisse von %eax bestimmen
|
|
orl 0x00100000, %eax
|
|
pushl %eax
|
|
|
|
movl %ebx, %eax # Mantisse von %ebx bestimmen
|
|
call significand
|
|
orl 0x00100000, %eax
|
|
movl %eax, %ebx
|
|
popl %eax
|
|
|
|
# 2 * 24 bit = 48 bit !!!!
|
|
mull %ebx # Mantissen multiplizieren
|
|
|
|
pushl %eax # Sichere neue Mantissse auf dem Stack
|
|
|
|
|
|
movl 4(%ebp), %ebx # ebx wieder herstellen
|
|
movl 8(%ebp), %eax # eax wieder herstellen
|
|
|
|
|
|
#Expoenten extrahieren und neuen Exponent bestimmen
|
|
call exponent
|
|
pushl %eax
|
|
|
|
movl %ebx, %eax
|
|
call exponent
|
|
movl %eax, %ebx
|
|
popl %eax
|
|
|
|
addl %ebx, %eax # Addiere beide Exponenten
|
|
subl $127, %eax # Exponenten - (1 x BIAS)
|
|
|
|
|
|
pushl %eax # Sichere neuen Exponentn auf dem Stack
|
|
|
|
|
|
|
|
#Berechne Vorzeichen des Produkts
|
|
movl 4(%ebp), %ebx # ebx wieder herstellen
|
|
movl 8(%ebp), %eax # eax wieder herstellen
|
|
|
|
|
|
call sign
|
|
movl %eax, %ebx
|
|
pushl %eax
|
|
|
|
movl %ebx, %eax
|
|
call sign
|
|
movl %eax, %ebx
|
|
popl %eax
|
|
|
|
xor %ebx, %eax
|
|
|
|
pushl %eax # Neuen Exponent auf Stack sichern
|
|
|
|
|
|
|
|
|
|
# Ergebnis zusammensetzen
|
|
|
|
|
|
|
|
|
|
|
|
ret
|
|
################################################################################################################################
|
|
|
|
|
|
|
|
/*
|
|
Ausgabe einer float Zahl via printf
|
|
Wichtig: printf ist leider nur double kompatibel,
|
|
daher muss float auf double erweitert werden
|
|
auch wenn %f genutzt wird!
|
|
|
|
Eingabe: %eax
|
|
Ausgabe: ---
|
|
*/
|
|
fltprint:
|
|
pusha
|
|
|
|
call extend # Wegen printf auf double erweitern
|
|
pushl %edx
|
|
pushl %eax
|
|
pushl $fltout
|
|
call _printf
|
|
addl $12, %esp
|
|
|
|
popa
|
|
ret
|
|
|
|
/*
|
|
Erweitert ein float in double
|
|
Eingabe: %eax
|
|
Ausgabe: %edx:%eax
|
|
|
|
Notizen: %ebx enthaelt dauerhaft den float-Wert
|
|
; %ecx:%edx Zwischenergebniss der Erweiterung
|
|
; %edx enthaelt Differenz der Exponenten
|
|
*/
|
|
extend:
|
|
pushl %ebx
|
|
pushl %ecx
|
|
|
|
movl %eax, %ebx # Sicherung des floats
|
|
call sign # Vorzeichen extrahieren
|
|
movl %eax, %ecx # ecx:edx wird double enthalten
|
|
movl %ebx, %eax
|
|
call exponent # Exponent extrahieren
|
|
addl $896, %eax # Exponent erweitern -127 +1023
|
|
shll $11, %ecx
|
|
orl %eax, %ecx # An ecx anhaengen
|
|
movl %ebx, %eax
|
|
call significand # Mantisse extrahieren
|
|
movl %eax, %edx
|
|
shrl $3, %eax # Nur 20 Bit passen noch dran
|
|
shll $20, %ecx
|
|
orl %eax, %ecx
|
|
shll $29, %edx # Mantisse erweitern
|
|
movl %edx, %eax # Ausgabe setzen
|
|
movl %ecx, %edx
|
|
|
|
popl %ecx
|
|
popl %ebx
|
|
ret
|
|
|
|
|
|
/*
|
|
Vorzeichen des floats extrahieren
|
|
Ein-/Ausgabe: %eax
|
|
|
|
Notizen: --AUSFUELLEN--
|
|
*/
|
|
sign:
|
|
shrl $31, %eax # %eax shiften
|
|
|
|
ret
|
|
|
|
/*
|
|
Exponent des floats extrahieren
|
|
Ein-/Ausgabe: %eax
|
|
|
|
Notizen: --AUSFUELLEN--
|
|
*/
|
|
exponent:
|
|
and $0x7F800000, %eax # exponent maskieren
|
|
shrl $23, %eax # %eax shiften
|
|
ret
|
|
|
|
/*
|
|
Mantisse des floats extrahieren
|
|
Ein-/Ausgabe: %eax
|
|
|
|
Notizen: --AUSFUELLEN--
|
|
*/
|
|
significand:
|
|
andl $0x007FFFFF, %eax # mantisse maskieren
|
|
ret
|
|
|
|
|