IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Assembleur Discussion :

Conversion de date et division 64 bits


Sujet :

Assembleur

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 80
    Points : 69
    Points
    69
    Par défaut Conversion de date et division 64 bits
    bon voila mon pb : je dev un "driver" en asm pour lire les partitions ntfs (a terme pour être inclus dans un OS, je n'ai donc accés à aucune fonction sur les dates,etc....), et dans ce systeme de fichiers les dates sont codés en unités de 100 ns écoulés depuis le 01/01/1601 !! le pire c'est que le nb est stocké sur 64 bits !!!

    je dois donc :
    1) transformer le nb sur 64bits en sec ; l'algo est simple mais je ne sais pas comment faire une division 64bits avec des regs 32 bits !!
    2) transformer le nb de secondes obtenues en date en l'ajoutant à la date du 1/1/1601, et la j'vois pas trop comment faire à part créer un mega calendrier.....

    bon ben voila, si qq'un peut m'aider , merci d'avance a+

  2. #2
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    chelou le NTFS !!
    pour la division 64 bits, ca doit facilement etre possible avec la methode du decalage et de la soustraction (je crois qu'il y a deja un post pour les multiplication, tu peux adapter)

    pour le caladar c pas si dur, c un algo pas tres compliqué, faut juste faire gaffe au année bimachin (une tous les quatre ans - une tous les 16 ans) mais la faut verifié (et je ne sais pas ou)

    au pire tu peux mater les sources de linux (si tu les trouves!)

    ps pour la division si tu y'arrive pa, je veux bien poster un exemple (c deux sources de 64 bits ??)

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 80
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par TangiX
    chelou le NTFS !!
    pour la division 64 bits, ca doit facilement etre possible avec la methode du decalage et de la soustraction (je crois qu'il y a deja un post pour les multiplication, tu peux adapter)

    pour le caladar c pas si dur, c un algo pas tres compliqué, faut juste faire gaffe au année bimachin (une tous les quatre ans - une tous les 16 ans) mais la faut verifié (et je ne sais pas ou)

    au pire tu peux mater les sources de linux (si tu les trouves!)

    ps pour la division si tu y'arrive pa, je veux bien poster un exemple (c deux sources de 64 bits ??)
    ouais chelou !!

    pour linux, laisse tomber, d'aprés ce que j'ai vu, sous linux/unix le stockage de la date, c'est à peu prés le même délire que ntfs, mais en partant d'une autre année, donc ils se contente de décaler la date, c'est + facile..

    oui j'veux bien un exemple de div avec a/b ou a=64b et b=32b c'est deja pas mal, si t'as le temps de faire la meme chose pour b=64b je suis preneur !!!!


    c'est quoi l'algo de calendrier dont tu parle ? pis il faut stocker un calendrier de (2004-1601)*365=147095 jours en ram quand même !!! en plus j'vois pas comment gérer l'eure dans tous ca .... ou alors tu voyais ca autrement ?....

  4. #4
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    pour la division, je me suis peut etre un peu avance ,mais j'crois etre sur une piste quand meme....

    pour le calandar, le but d'avoir un algo c justement de ne rien stocker en mémoire !!!
    bon d'acord c pa evident je vais cherche aussi...apres la div!
    essaye sur google je suis sur qu'il y a des code libre qui existe la dessus

    bon dev'

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 80
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par TangiX
    pour la division...
    pour le calandar...
    ok , merci , bon on cherche et on se tient au courant , ok ?

  6. #6
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    pour la division, g trouvé qqch mais c pa genial du tout (je suis en train d'en faire une sur mon autre PC et c tjrs pa fini !) t sur que tu va pa faire un os juste pour l'archi x86-64
    g utilisé la technique qu'on utilise au primaire pour faire une division a la main ! (tu veux qd meme le code ?)
    si qqun connait une meilleure technique, faut pa hesiter a annoncer !
    sinon on peut toujours ouvrir un x86-64 et voir comment y font avec un microscope !!

    bon dev'

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par dway
    oui j'veux bien un exemple de div avec a/b ou a=64b et b=32b c'est deja pas mal
    [doc intel]
    F7 /6 DIV r/m32 : Unsigned divide EDX:EAX by r/m32, with result stored in EAX ← Quotient, EDX ← Remainder
    F7 /7 IDIV r/m32 : Signed divide EDX:EAX by r/m32, with result stored in EAX ← Quotient, EDX ← Remainder
    [/doc intel]

    ça te fera pas de divisions entre 2 nombres de 64 bits, mais pour l'exemple que tu as demandé il me semble que ça marche non ?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    Sinon tu peux passer par le fpu pour a=64b et b=64b

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    a   dq   ?
    b   dq   ?
    r   dq   ?
     
    fild qword ptr [a]
    fild qword ptr [b]
    fdivp
    fistp qword ptr [r]

  9. #9
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    tout de suite l'algo est plus facile a trouvé

    je cherche du coté de la date maintenant...

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 80
    Points : 69
    Points
    69
    Par défaut
    ok merci les gars je teste ca et je vous dis quoi...

    les instructions fild,fdivp et fistp c'est accessible à partir de quel proc ? 486 non ?

    ps : Chris_hks, t'as vu mon mail tu ntfs stp ?

  11. #11
    Invité
    Invité(e)
    Par défaut
    Il est n'est pas utile de passe par la FPU pour des divisions 64 par 64 est c'est même déconseiller: la précision n'est pas suffisante (15-16 chiffre avec des doubles).
    Le code suivant est extrait de la doc AMD "AMD Athlon™ Processor x86 Code Optimization Guide" téléchargeable sur le site AMD:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    ;_ulldiv divides two unsigned 64-bit integers, and returns
    ; the quotient.
    ;
    ;INPUT: [ESP+8]:[ESP+4] dividend
    ; [ESP+16]:[ESP+12] divisor
    ;
    ;OUTPUT: EDX:EAX quotient of division
    ;
    ;DESTROYS: EAX,ECX,EDX,EFlags
     
    _ulldiv PROC
     
            PUSH EBX          ;save EBX as per calling convention
            MOV ECX, [ESP+20] ;divisor_hi
            MOV EBX, [ESP+16] ;divisor_lo
            MOV EDX, [ESP+12] ;dividend_hi
            MOV EAX, [ESP+8]  ;dividend_lo
            TEST ECX, ECX     ;divisor > 2^32–1?
            JNZ $big_divisor  ;yes, divisor > 32^32–1
     
            CMP EDX, EBX      ;only one division needed? (ECX = 0)
            JAE $two_divs     ;need two divisions
            DIV EBX           ;EAX = quotient_lo
            MOV EDX, ECX      ;EDX = quotient_hi = 0 (quotient in ; EDX:EAX)
            POP EBX           ;restore EBX as per calling convention
            RET               ;done, return to caller
     
     $two_divs:
            MOV ECX, EAX      ;save dividend_lo in ECX
            MOV EAX, EDX      ;get dividend_hi
            XOR EDX, EDX      ;zero extend it into EDX:EAX
            DIV EBX           ;quotient_hi in EAX
            XCHG EAX, ECX     ;ECX = quotient_hi, EAX = dividend_lo
            DIV EBX           ;EAX = quotient_lo
            MOV EDX, ECX      ;EDX = quotient_hi (quotient in EDX:EAX)
            POP EBX           ;restore EBX as per calling convention
            RET               ;done, return to caller
     $big_divisor:
            PUSH EDI          ;save EDI as per calling convention
            MOV EDI, ECX      ;save divisor_hi
            SHR EDX, 1        ;shift both divisor and dividend right
            RCR EAX, 1        ; by 1 bit
            ROR EDI, 1
            RCR EBX, 1
            BSR ECX, ECX      ;ECX = number of remaining shifts
            SHRD EBX, EDI, CL ;scale down divisor and dividend
            SHRD EAX, EDX, CL ; such that divisor is
            SHR EDX, CL       ; less than 2^32 (i.e. fits in EBX)
            ROL EDI, 1        ;restore original divisor_hi
            DIV EBX           ;compute quotient
            MOV EBX, [ESP+12] ;dividend_lo
     
            MOV ECX, EAX      ;save quotient
            IMUL EDI, EAX     ;quotient * divisor hi-word
                              ; (low only)
            MUL DWORD PTR [ESP+20] ;quotient * divisor lo-word
            ADD EDX, EDI           ;EDX:EAX = quotient * divisor
            SUB EBX, EAX           ;dividend_lo – (quot.*divisor)_lo
            MOV EAX, ECX           ;get quotient
            MOV ECX, [ESP+16]      ;dividend_hi
            SBB ECX, EDX           ;subtract divisor * quot. from dividend
            SBB EAX, 0             ;adjust quotient if remainder negative
            XOR EDX, EDX           ;clear hi-word of quot(EAX<=FFFFFFFFh)
            POP EDI                ;restore EDI as per calling convention
            POP EBX                ;restore EBX as per calling convention
            RET                    ;done, return to caller
     
    _ulldiv ENDP
    On peut aussi utiliser les instructions MMX et l'algo que j'avais donné dans le post
    http://www.developpez.net/forums/vie...hlight=#345952

    A+

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 80
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par AMILIN
    Le code suivant ...
    ok merci ca fonctionne bien apparement, le (nouveau) souci que j'ai maintenant, c'est que je vais devoir gérer les nb à virgules pour pouvoir gérer les heures .....

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    AMILIN ton code ne marche qu'avec des non-signés, et en plus je trouve que c'est une grosse tartine indigeste, mais ça c'est un avis personnel, c'est probablement plus rapide ta méthode. Et je vois pas en quoi le fpu n'est pas précis, il travaille avec des floats codés sur 80 bits

  14. #14
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    80bits pour un real a mon avis avis ca fait pas 64bits pour la mantise...
    ca ferait juste un truc genre 14 bit pour l'exposant ...16000... je sais plus...

    sinon pour le calandar, je comprend mieux le coup du 1/1/1601, c du au années bissextiles !
    les années bissextiles sont tous les multiples de 4... sauf si c un multiple de 100.... sauf si c un multiple de 400, or le dernier multiple de 400 precedent l'aire informatique dans le calandrier gregorien... c 1600!!
    donc une periode 400 ans a toujours le meme nbre de jours ds laquelle les trois premieres periodes de 100 ans ont le meme nbre de jour etc
    donc pour trouver l'année c super simple, l'algo est exactement le meme qu'une conversion de base !
    pour les mois ca doit etre plus dur, mais on peut faire un tableau ou autre chose avoir...

    bon dev'

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    64 bits de mantisse, 15 d'exposants et 1 de signe

  16. #16
    Membre habitué
    Avatar de TangiX
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 139
    Points : 168
    Points
    168
    Par défaut
    ok g rien dit ....

  17. #17
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Chris_hks
    AMILIN ton code ne marche qu'avec des non-signés, et en plus je trouve que c'est une grosse tartine indigeste, mais ça c'est un avis personnel, c'est probablement plus rapide ta méthode. Et je vois pas en quoi le fpu n'est pas précis, il travaille avec des floats codés sur 80 bits
    Dans la docs "AMD Athlon™ Processor x86 Code Optimization Guide" il y a aussi les divisions 64 bits signés... Si tu trouve le code indigeste sache que l'algo utilisé ici est le même que pour la divsion à la main mais en base 2^32 plutôt que la base 10.

    Pour la FPU la précision est de 63 bits.
    La mantisse est bien de 64bits MAIS le 64ème bits vaut toujours 1 d'ou une précision de 63 bits. D'après toi, pourquoi l'implémentation des compilateurs C/C++ n'utilise pas la FPU pour les /,* avec le type __int64 (ou long long) ?

    A+

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par AMILIN
    Si tu trouve le code indigeste sache que l'algo utilisé ici est le même que pour la divsion à la main mais en base 2^32 plutôt que la base 10.
    C'est censé me rassurer ?

    Citation Envoyé par AMILIN
    Pour la FPU la précision est de 63 bits.
    La mantisse est bien de 64bits MAIS le 64ème bits vaut toujours 1 d'ou une précision de 63 bits. D'après toi, pourquoi l'implémentation des compilateurs C/C++ n'utilise pas la FPU pour les /,* avec le type __int64 (ou long long) ?
    parce que le C/C++ est le C/C++. C'est un langage évolué, avec un compilateur qui transforme les mots-clés tapés par le programmeur en assembleur, et ce compilateur tout ce qu'on lui demande c'est de produire du code efficace, il ne se soucie pas de la lisibilité de ce code. Seulement ici c'est le forum assembleur. Mais je te garantis une fois de plus que tu auras toute la précision nécessaire si tu traites des __int64 avec le fpu. Essaye par toi-même, tu déclares des __int64, tu leurs donnes toutes les valeurs que tu veux, les plus grandes et plus petites possibles, peu importe, ensuite tu les load dans le fpu avec fild et tu les store avec fistp. Tu verras qu'il va te cracher des nombres strictement identiques dans tous les cas.

  19. #19
    Invité
    Invité(e)
    Par défaut
    a = 2^63-1 = 9223372036854775807
    b = 2^62 = 4611686018427387904

    a/b = 1.999999999999999999783159 (calculé avec Maple) et donc dépasse la précision.

    avec la FPU a/b=2 et le vrai quotient est 1 !!!

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Août 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    es-tu vraiment sûr que dway a besoin de cette précision ?
    Mais je ne conteste pas, tu as raison pour ça. De toute façon le fpu n'est pas fait pour traiter des entiers, et pour cause, ça veut bien dire floating point unit, c'était une solution de dépannage (et elle venait pas d'un manuel d'AMD mais de ma tête :p c'est peut-être pour ça qu'elle était pas géniale lol).

Discussions similaires

  1. Probleme de conversion de dates
    Par manu00 dans le forum Langage
    Réponses: 4
    Dernier message: 29/05/2005, 00h00
  2. Conversion de date
    Par jdu dans le forum Access
    Réponses: 2
    Dernier message: 26/01/2005, 16h17
  3. Conversion de dates
    Par Gogoye dans le forum Modules
    Réponses: 5
    Dernier message: 10/08/2004, 11h39
  4. - [CAST ou CONVERT] Problème de conversion de date
    Par Boublou dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 06/07/2004, 14h31
  5. Conversion de date lors d'un import
    Par bilbon.S dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 26/03/2004, 14h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo