PDA

View Full Version : [ASSEMBLY] Operazioni su float


HipT
15-07-2012, 00:54
Ciao a tutti,

Premetto che sono piuttosto disperato (si può capire anche dall'ora in cui sto scrivendo) perchè dopo averci sbattuto la testa per giorni non sono riuscito a darne fuori.
Utilizzo la sintassi AT&T e compilatore as interno a linux.
Il problema,devo eseguire un'operazione che richiedede una divisione e una moltiplicazione.Inizialmente ho utilizzato i comandi idiv e imul.
Ma ho notato che queste istruzioni eseguono solo operazioni tra numeri interi.
Ho così provato a utilizzare le istruzioni "fimul" e "fidiv" per calcolare su float.
Il programma compila ma penso che questi 2 comandi per float operino su registri diversi rispetto la loro controparte intera inquanto i risultati sono sballati non di poco (ma non sballati da valori stile overflow o errore di lettura tra byte/word etc)
Qualcuno cortesemente potrebbe farmi un esempio con una divisione e una moltiplicazione tra float in modo da capire su che registri operano?

Grazie in anticipo!

AnonimoVeneziano
15-07-2012, 13:43
Ciao a tutti,

Premetto che sono piuttosto disperato (si può capire anche dall'ora in cui sto scrivendo) perchè dopo averci sbattuto la testa per giorni non sono riuscito a darne fuori.
Utilizzo la sintassi AT&T e compilatore as interno a linux.
Il problema,devo eseguire un'operazione che richiedede una divisione e una moltiplicazione.Inizialmente ho utilizzato i comandi idiv e imul.
Ma ho notato che queste istruzioni eseguono solo operazioni tra numeri interi.
Ho così provato a utilizzare le istruzioni "fimul" e "fidiv" per calcolare su float.
Il programma compila ma penso che questi 2 comandi per float operino su registri diversi rispetto la loro controparte intera inquanto i risultati sono sballati non di poco (ma non sballati da valori stile overflow o errore di lettura tra byte/word etc)
Qualcuno cortesemente potrebbe farmi un esempio con una divisione e una moltiplicazione tra float in modo da capire su che registri operano?

Grazie in anticipo!

Se stai lavorando su x86 (come credo) allora per i numeri a virgola mobile l'instruction set è decisamente diverso e lavora anche su registri differenti.

Le strade sono 2:

- Usi l'instruction set x87 , che è l'instruction set floating point storico del x86, supportato fin dai tempi del 386/486

- Usi le SSE2 , supportate su tutti i processori moderni, dal pentium4 in poi.

Nel caso di x87 l'instruction set funziona con registri che vengono gestiti come uno stack.
Un esempio di moltiplicazione tra due numeri è questo (uno è contenuto in $ebp-4 e l'altro in $ebp-8 , mentre il risultato è memorizzato in $ebp-12):


flds -4(%ebp) ; carica il primo numero nel registro TOP of the stack (ST(0))
fmuls -8(%ebp) ; moltiplica il numero in ebp-8 con il TOP of the stack e salva il risultato nel TOP (ST(0))
fstps -12(%ebp) ; memorizza il risultato in ebp-12 come un float a singola precisione



con SSE2 invece può essere similmente:


movss -4(%ebp), %xmm0 ; copia il numero in ebp-4 come float in singola precisione nel registro XMM0
mulss -8(%ebp), %xmm0 ; moltiplica il numero in ebp-8 con il valore nel registro XMM0 e memorizza là il risultato
movss %xmm0, -12(%ebp) ; memorizza il risultato in ebp-12



Per l'assembly x87 c'è una mini guida qui:

http://en.wikibooks.org/wiki/X86_Assembly/Floating_Point
però con sintassi Intel.

Per SSE cerca in giro e leggiti il manuale della INTEL.

Ciao

HipT
19-07-2012, 13:23
Scusa il ritardo,mi sono completamente dimenticato di rispondere :muro:
La tua risposta è stata utilissima!Ho finito per usare IS dell'x87 perchè avevo delle restrizioni sulla compilazione del programma.

Grazie!

AnonimoVeneziano
19-07-2012, 19:12
Scusa il ritardo,mi sono completamente dimenticato di rispondere :muro:
La tua risposta è stata utilissima!Ho finito per usare IS dell'x87 perchè avevo delle restrizioni sulla compilazione del programma.

Grazie!

Prego ;)

Grazie per avermi fatto sapere come è andata :)