|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
[NASM x86] Convertire uint64 in double
Ciao a tutti,
come potete vedere nella mia firma sto scrivendo un sistema operativo: Cosmos! E' scritto in C# e per certi versi è la versione Open Source dei progetti di ricerca Singularity e Midori. La differenza rispetto a un sistema operativo classico è che il runtime .NET è integrato nel Sistema Operativo stesso e tutte le istruzioni IL devono essere convertite in assembler prima ancora di creare il kernel. E' un po di tempo che sto impazzendo con l'instuzione conv.r.un che prende in input un uint32 o un uint64 e lo converte in double. Purtroppo non esiste né per la FPU x87 né SSE un'istruzione diretta per effettuare questa conversione quindi fa fatta "a mano". Questo è quello che ho cercato di fare io: Codice:
# in ESP c'è un ulong, prendiamo la parte alta e la mettiamo in EAX mov EAX, [ESP + 32] # Convertiamo l'ulong in double e salviamo in ST0 fild qword ptr [ESP] # Shift a destra di EAX fino al byte 31 shr EAX, 31 # Confrontiamo EAX con 0 cmp EAX, 0 # Se è 0 abbiamo finito saltiamo in LabelSign_Bit_Unset jpe LabelSign_Bit_Unset # Se è 1 dobbiamo togliere il segno dal double fadd dword ptr __ulong2double_const2 # salviamo il risultato in ESP LabelSign_Bit_Unset: fstp ESP Il problema è proprio che non trovo qual è questa constante per ora ho provato con 0x0000000000405BC0 (c'è una matematica complicatissima dietro, ma ve la evito ![]() ![]() Idee? Soluzioni? Insulti?
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 25-06-2016 alle 14:12. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4906
|
Non conosco NASM ma in MASM dovrebbe essere qualcosa del genere:
Codice:
.386 .model flat .data uint64add dd 5F800000h .code mov eax, dword ptr [esp+4] fild qword ptr [esp] test eax, eax jns short isuint32 fadd ds:uint64add isuint32: fstp qword ptr [esp] end |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
![]() Codice:
CVTSI2SD xmm, r/m32 ; Da sint32 a double CVTSI2SD xmm, r/m64 ; Da sint64 a double - se l'MSB del valore intero è zero, puoi convertirlo così com'è; - altrimenti rimuovi l'MSB, lo converti in double, e poi gli aggiungi 2^31 o 2^63 (con opportune costanti double).
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4906
|
Codice:
.386 .mmx .xmm .model flat .data align 16 xmm_sub dd 0, 43300000h, 0, 45300000h align 16 xmm_interleave dd 43300000h, 45300000h, 0, 0 .code movq xmm1, qword ptr [esp] punpckldq xmm1, xmmword ptr [ds:xmm_interleave] subpd xmm1, xmmword ptr [ds:xmm_sub] pshufd xmm0, xmm1, 00011110b addpd xmm0, xmm1 movq qword ptr [esp], xmm0 end |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
Codice:
mov dword EAX, [ESP + 4] fild qword [ESP] test dword EAX, EAX JNS near LabelSign_Bit_Unset fadd qword [0x5F800000] LabelSign_Bit_Unset: fstp dword [ESP] @cdimauro Attualmente il compilatore di Cosmos ha come target x86 a 32 Bit anch'io speravo di poter usare SSE per tutto, ma pare che quando si opera sui long non sia possibile, l'istruzione CVTSI2SD opera sempre su sint32, infatti quella che dovrei usare è CTVSQ2SD, ma esiste solo su IA64! O almeno così questi signori mi hanno convinto: http://forum.osdev.org/viewtopic.php?f=1&t=30324 La seconda versione che usa punpckldq mi spaventa un po' avevo visto una versione simile usata da Clang, ma sinceramente non so proprio come tradurla in NASM. L'idea di usare NASM che mi pare non usi nessuno per creare l'assembler mi sembra una scelta proprio sbagliata! Lavoriamo su Windows con Visual Studio (quindi no per ora di creare Cosmos su Linux non ce ne frega nulla) perché non usare l'assembler della Microsoft MASM che sembra molto più avanzato? E soprattutto il cui assembler è molto più conosciuto? E che posso chiedere a Visual Studio di mostrarmi usando i breakpoint? Comunque stiamo provando a scrivere il nostro High Level Assembler che sarà integrato con C# e che si chiama X# (X sta per X86, in futuro esisterà anche A# per ARM!), infatti io non scrivo NASM direttamente, ma questo: Codice:
// Save the high part of the ulong in EAX (we cannot move all of ESP as it has 64 bit size) XS.Set(EAX, ESP, sourceIsIndirect: true, sourceDisplacement: 4); XS.FPU.IntLoad(ESP, isIndirect: true, size: RegisterSize.Long64); // Get its highest bit to check if the value was signed or unsigned //XS.ShiftRight(EAX, 31); //XS.Compare(EAX, 0x00); //XS.Jump(ConditionalTestEnum.Equal, LabelSign_Bit_Unset); XS.Test(EAX, EAX); XS.Jump(ConditionalTestEnum.NotSign, LabelSign_Bit_Unset); //XS.LiteralCode(@"fadd qword [__ulong2double_const3]"); XS.LiteralCode(@"fadd qword [0x5F800000]"); XS.Label(LabelSign_Bit_Unset); XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size:RegisterSize.Long64); Ma il vero X# è ancora meglio: https://en.wikipedia.org/wiki/X_Sharp ma dobbiamo studiare come embeddarlo dentro a C#...
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 26-06-2016 alle 13:11. |
|
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4906
|
Quote:
Quote:
Codice:
.386 .mmx .xmm .model flat .data dq_add dq 0 dq_mul dq 41F0000000000000h .code mov eax, dword ptr [esp] cvtsi2sd xmm0, eax shr eax, 1Fh addsd xmm0, qword ptr [ds:dq_add+eax*8] mov eax, dword ptr [esp+4] test eax, eax jz short store cvtsi2sd xmm1, eax shr eax, 1Fh addsd xmm1, qword ptr [ds:dq_add+eax*8] mulsd xmm1, qword ptr [ds:dq_mul] addsd xmm0, xmm1 store: movq qword ptr [esp], xmm0 end |
||
![]() |
![]() |
![]() |
#7 | ||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
) ed invece no ![]() Ho pensato che fosse il little endian a fregarmi e così ho invertito la tua constante che è diventata 0x00000805F, beh il risultato ottenuto è F0BF, ma dovrebbe essere F043. Il valore da me usato è uno che sicuramente dovrebbe risultare segnato: -1 che visto come ulong è un numeraccio: 18446744073709551615 (in hex è ovviamente 8 volte F) eppure sembra che EAX sia non segnato visto che la fadd non ha effetto! Non capisco... Quote:
La vera soluzione sarebbe usare AVX, ma già abbiamo tagliato via tutto quello che c'è prima del PIII usando SSE2 per avere le istruzioni di conversione int <--> double così funzioneremmo solo su PC dal 2007 in poi ![]()
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
||
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4906
|
Esattamente che valori hai in input e output?
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
In input ho -1 che però espresso in ulong è 18446744073709551615 il risultato atteso è un double il cui valore in hex è F043 (ovviamente stampato come double è 18446744073709551615.0) invece ottengo F0BF (-1.0 come double). Ho pensato di usare -1 come "caso più semplice" ho un bit pattern con tutti 1 e invece il test dice che ho uno 0 in MSB... non ha senso!
Se potessi provare anche tu mi fai un piacere... Sono ormai quasi convinto che è un bug o di NASM (che genera x86 errato) o di Bochs che non setta correttamente EAX!
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 26-06-2016 alle 19:35. |
![]() |
![]() |
![]() |
#10 | |||
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
Se volete sperimentare coi soli puntatori a 32-bit, allora utilizzate l'ABI x32, che gira sempre in modalità x64 e, quindi, ne consente di sfruttare tutti i benefici, ma mantiene soltanto i puntatori a 32 bit, per alleggerire la pressione su data cache et similia. Quote:
![]()
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|||
![]() |
![]() |
![]() |
#11 | ||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
Quote:
Sì x32 è una strada che mi piacerebbe percorrere anche se non ho capito se in ambito .NET è la stessa cosa del flag /prefer32. Di certo "sprecare" memoria per i puntatori a 64 bit quando le applicazioni che hanno bisogno di più > 4 GB di memoria si contano sulle dita di una mano pare un po' un spreco. Sì un kernel a 64 (o 32x) che permette di far girare le applicazioni che lo richiedono a 32 Bit o 64 Bit sarebbe l'ideale! Questo è quello che mi eccita di più di questo progetto non abbiamo 30 anni di retrocompatibilità tra le scatole e possiamo pensare a cose veramente nuove. Per esempio 32x che a me pare un'ottima idea su Linux non se lo è c*gato nessuno perché c'erano i 30 di x86 e visto che era incompatibile la gente si è chiesta qual è il senso? Fico! Come si chiamava?
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 26-06-2016 alle 21:48. |
||
![]() |
![]() |
![]() |
#12 | |||||
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
![]() Galileo supporta soltanto l'ISA Pentium, e dunque hai soltanto l'FPU e nessuna unità SIMD (nemmeno MMX). Con Edison ti va molto meglio, perché l'ISA Silvermont, e dunque fino alle SSE4.2. Ma niente AVX, purtroppo. Solo che non so se specificamente per Edison sia disponibile anche la modalità a 64 bit. Quote:
![]() Quote:
Ovviamente nessuno t'impedisce di realizzare un backend .NET per x32, magari partendo da quello x64. Quote:
Quote:
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|||||
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Jan 2014
Messaggi: 3826
|
Ma sapete che 'sto Cosmos mi sta intrippando? Quasi quasi, appena mi libero un po' con la tesi (Aaaaaah, le catene di Markov...
![]() ![]() |
![]() |
![]() |
![]() |
#14 | |||||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Ieri sera abbiamo messo Bochs in modalità debug e siamo andati a vedere step per step cosa c'era nei registri vi faccio un breve riassunto:
Quindi questa è la domanda da un milione di Euro: come può un'addizione non avere effetto? L'unico caso in matematica è quando l'addendo vale 0, ma qui valeva 0x5F800000! Forse è perché la constante è un double mentre in FP0 c'è un long double? Vede solo gli ultimi 5 zeri? Beh non è che ci lavoro solo io eh! Non sono nemmeno il capo del team io mi sono aggiunto solo di recente (volevo il cursore quadrato e blikante tipo C=64 e poi son finito a scrivere assembler in C# ![]() Quote:
A me piacerebbe che Cosmos riuscisse a farlo in automatico magari interrogando alla partenza la CPU per vedere quale istruzioni supporta e poi con qualche symbol table chiamare una funzione piuttosto che un'altra, ma visto che l'assembler dobbiamo crearlo a compile time beh è un po' difficile farlo: andrebbero lasciati dei "buchi" nell'assembler stesso! Quote:
Abbiamo valutato che la compatibilità con i processori troppo vecchi non avesse alcun senso per un OS del 2016 inoltrato! Quote:
![]() Quote:
Quote:
Non capisco perché la Microsoft non abbia fatto la mossa coraggiosa per Windows 10 e non sia ancora passata a .NET per tutto. Temo che il vero motivo sia il solito i 30 anni di compatibilità con X86! @GTKM Magari! Saresti solo che il benvenuto.
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 27-06-2016 alle 09:37. |
|||||
![]() |
![]() |
![]() |
#15 | |||||
Senior Member
Iscritto dal: Jan 2014
Messaggi: 3826
|
Quote:
Quote:
Quote:
![]() Quote:
Quote:
![]() |
|||||
![]() |
![]() |
![]() |
#16 | |||||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Quote:
Quote:
GCC risolve il problema nel modo più banale di default compila per 486 (quindi solo FPU legacy, niente MMX, ...) e poi se uno lo richiede aggiungendo opportunamente dei flag nella linea di comando puoi usare mmx, sse1, see2, ... Noi per fare in questo modo faremmo dei profili in Visual Studio tutti carucci però a me piacerebbe una soluzione più "automatica" la mia idea non sarebbe troppo lontana da avere un JIT solo per alcun istruzioni, ma non farlo tutte le volte che sono incontrate, ma solo alla partenza del Kernel interrogando la CPU stessa con CPUID. Mi hanno che sarebbe possibile farlo usando indirect call, ma sarebbe molto più lento che avere l'assembler già pronto. Per ora comunque il target è farlo girare su un normale x86 dal Pentium III in poi... Quote:
Quote:
Quote:
* In un OS language based come Midori e Cosmos codice "nativo" non può / non deve girare se no cadrebbe lo scopo per cui è stato scritto. Solo applicazioni .NET che vengono trasformate in assembler ad installation time... quindi no niente Firefox (!), Python sì lo si potrà avere nella forma di Iron Python però...
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 27-06-2016 alle 11:31. |
|||||
![]() |
![]() |
![]() |
#17 | ||||
Senior Member
Iscritto dal: Jan 2014
Messaggi: 3826
|
Quote:
![]() Quote:
Secondo me è poco elastica come soluzione, sinceramente. Quote:
![]() Quote:
![]() Riguardo il codice "nativo", beh, in un certo senso è come se il codice scritto in C# lo sia già, per Cosmos, no? |
||||
![]() |
![]() |
![]() |
#18 | |||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Già, ma è impossibile però! Deve essere qualche errore stupido e banali di quelli che rileggi il codice mille volte e ti pare giusto poi arriva il collega che non centra una fava e bam...
Quote:
Semplicemente su Cosmos durante l'installazione / prima esecuzione viene compilato in assembler un po' come fa NGEN. Credo sia addirittura possibile mettere il codice binario dentro l'eseguibile stesso. Le volte successive è il codice binario che verrà eseguito! Quote:
Vedi in teoria è molto bello avere un OS che occupa pochi MB peccato che poi ti trovi busybox che fa schifo, scopri che la libinconv "ritagliata" non supporta la codepage che ti serve e quindi sei sempre a ricompilarla, che l'UTF-8 "ritagliato" in realtà da errore se vede multi byte characters... Secondo me dentro .NET c'è il minimo necessario per avere un OS / runtime che ha senso. Eh lo so, però un'azienda come Microsoft campa(va) su quello, quindi non è che potesse tagliare decennia di compatibilità Fosse stato possibile, sono sicuro che I loro dev sarebbero stati i primi ad esultare. ![]() Quote:
C/C++ o assembler sono vietate perché:
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! |
|||
![]() |
![]() |
![]() |
#19 | ||||
Senior Member
Iscritto dal: Jan 2014
Messaggi: 3826
|
Quote:
![]() Quote:
Quote:
![]() Quote:
|
||||
![]() |
![]() |
![]() |
#20 | |||
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2095
|
Sono in chat con Matthijs ter Woord, il nostro Linus Torvald, solo che è molto più educato: non ha ancora mandato a fare in c*lo nessuno!
E mi chiedeva cosa ci fanno le [ ] davanti alla costante della fadd? In effetti non sono sicuro nemmeno io che abbia senso, ma il codice MASM originale la passava come puntatore 'ptr .label'... può essere questo il problema... magari Bochs è "educato" e anche se punto a RAM a caso mi trovo tutti 0? Quote:
Nota che per ora Cosmos è super monolitico non abbiamo ancora il supporto per i thread (processi in altri OS) quindi per ora le "applicazioni" sono chiamate a funzione dentro la shell! Quote:
![]() Quote:
joeduffyblog.com/2015/12/19/safe-native-code/
__________________
Cosmos C# Open Source Managed Operating System Cosmos Thread Ufficiale Cosmos Official Site Vuoi collaborare allo sviluppo? Unisciti alla chat! Ultima modifica di fano : 27-06-2016 alle 15:19. |
|||
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:49.