Sto appena iniziando a imparare l'assemblaggio nella mia classe di informatica e ho un compito di arrotondare un valore in virgola mobile utilizzando una modalità di arrotondamento specificata . Ho provato a implementarlo utilizzando fstcw
, fldcw
e frndint
. Modificare i bit di controllo dell'arrotondamento, arrotondare il numero e ripristinare i bit di controllo precedenti (requisito per l'assegnazione).Utilizzo di numeri a precisione doppia nel montaggio in linea (GCC, IA-32)
L'attuale problema notevole è che l'istruzione fld %1
sembra caricare il valore errato nel registro st(0)
virgola mobile (ad esempio, se chiamo la funzione con un valore di 2,6207, il numero -1,9427 (...) e-29 viene caricato nel registro). Ciò potrebbe essere dovuto a un uso improprio di asm()
in linea gcc
o altro, ma non sono sicuro del motivo.
Ecco quello che ho:
double roundD (double n, RoundingMode roundingMode)
{
// control word storage (2 bytes for previous, 2 for current)
char *cw = malloc(4*sizeof(char));
char *cw2 = cw + 2;
asm("fstcw %3;" // store control word in cw
"mov %3,%4;" // copy control word into cw2
"and $0xF3FF,%4;" // zero out rounding control bits
"or %2,%4;" // put new mode into rounding control bits
"fldcw %5;" // load the modified control word
"fld %1;" // load n into st(0)
"frndint;" // round n
"fstp %0;" // load st(0) back into n
"fldcw %3;" // load the old control word from cw
: "=m" (n)
: "m" (n), "m" (roundingMode),
"m" (cw), "r" (cw2), "m" (cw2) // mov requires one argument in a register
);
free(cw);
return n;
}
Apprezzerei tutto puntatori a cosa c'è di sbagliato in questo codice, in particolare in relazione alla linea fld %1
ei asm
ingressi/uscite. (Naturalmente, se riesci a trovare altri problemi, sentiti libero di farmi sapere anche su di loro.) Non voglio che nessuno faccia i miei compiti per me, semplicemente indicami la giusta direzione. Grazie!
Wow, è abbastanza cazzuto. Vorrei poterti aiutare, ma non posso! :) –
puoi mostrarci l'output di assemblaggio di questa funzione? e il codice byte anche se non è troppo disturbo. –
@John: il codice che verrà assemblato non è una sorpresa; è tutto in un blocco opaco gigante (a gcc) asm. :-P Considerando che dividerlo in molte dichiarazioni su asm (come il mio post) darebbe a gcc più spazio per fare qualcosa di diverso. –