6
votes

Comment puis-je accéder au temps système à l'aide de NASM?

Comment puis-je accéder à l'heure du système en utilisant Nasm , sur Linux? < / p>

(Remarque de l'éditeur: La réponse acceptée est destinée à DOS 16 bits avec accès matériel direct; cela fonctionnerait à l'intérieur de la DOSBOX. Les autres réponses sont en réalité pour Linux.)


5 commentaires

Type d'une grosse édition mais j'ai essayé de faire la question approximative de ce que je pensais que l'OP demandait ...


Pouvez-vous utiliser un système d'appel système / / dev de fichier de fichiers?


EXEMPLE DE FONCTIONNEMENT QEMU 16 bits Exemple: Github.com / CIROSANTLLI / X86-BAR-METAL-EXEMPLES / BLOB / ... Pouvez-vous utiliser le système de fichiers d'appel système / / dev?


Tout comme un côté, si ce générateur de nombres est utilisé cryptographiquement, c'est une idée terrible. Le temps n'est pas entropic


Cette question a été mentionnée à l'origine en utilisant le temps comme une graine pour une RNG. Sur Linux, open / lue / dev / urandom pour obtenir entropie ou utilisez simplement rdtsc si vous voulez une entropie basée sur le temps-réinitialisé et ne vous souciez pas de le sens réel que le temps. J'ai édité la question de supprimer cette motivation car les futurs lecteurs trouvant que cette question de Google veut probablement réellement le moment de la journée.


5 Réponses :


5
votes

sur le métal nu (dans un système d'exploitation personnalisé) ou dans un programme DOS:

%define RTCaddress  0x70
%define RTCdata     0x71

;Get time and date from RTC

.l1:    mov al,10           ;Get RTC register A
    out RTCaddress,al
    in al,RTCdata
    test al,0x80            ;Is update in progress?
    jne .l1             ; yes, wait

    mov al,0            ;Get seconds (00 to 59)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeSecond],al

    mov al,0x02         ;Get minutes (00 to 59)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeMinute],al

    mov al,0x04         ;Get hours (see notes)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeHour],al

    mov al,0x07         ;Get day of month (01 to 31)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeDay],al

    mov al,0x08         ;Get month (01 to 12)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeMonth],al

    mov al,0x09         ;Get year (00 to 99)
    out RTCaddress,al
    in al,RTCdata
    mov [RTCtimeYear],al

    ret


5 commentaires

Je suis un peu confus. Est-ce que cela fonctionne sur l'hypothèse que l'affiche utilise Windows?


Devrait fonctionner pour tout système d'exploitation sur X86 qui maintient sa date / heure du système.


Il suffit d'essayer - malheureusement, "Out RTCAddress, al" échoue sur Vista64 en raison du niveau de privilège.


Ah, je ne sais pas vraiment alors. Comme je l'ai dit, cela devrait travailler sur x86, pas x64, encore moins avec la sécurité glorieuse de Vista, hehe.


Cela ne fonctionnera pas dans aucun système de style UNIX, y compris Linux, qui est ce que l'OP a demandé. Vous ne pouvez pas accéder aux ports matériels directement en dehors du noyau, mais il faut plutôt utiliser l'interface int 0x80 pour y arriver.



0
votes

Je dirais, selon la plate-forme que vous allez, vous devrez utiliser une fonction OS.

sur Windows, essayez GetSystemTime . Sur Linux, essayez gettimeOfday - voir la question associée ici .


0 commentaires

7
votes

Utilisation de code 32 bits sous Linux:

mov  eax, 13         ; call number = __NR_time
xor  ebx, ebx        ; tloc = NULL
int  0x80
; 32-bit time_t in EAX


1 commentaires

Ou simplement passer NULL et utilisez le TIME_T qui est retourné dans EAX comme valeur de retour d'appel système. man7.org/linux/man-pages/man2/time.2. HTML dit Le TLOC est obsolète et doit toujours être null dans le nouveau code. Il est inutile de demander également au noyau de le stocker ailleurs.



4
votes

Avec NASM, si vous ciblez Linux X86-64, vous pouvez simplement effectuer ce qui suit: xxx

201 correspond au numéro d'appel du système 64 bits pour sys_time (comme indiqué sur Ici ). Registre RDI est défini sur 0 afin que la valeur de retour après l'exécution de l'appel système est stockée dans RAX , mais vous pouvez également le faire indiquer un emplacement de mémoire de votre choix. Le résultat est exprimé en quelques secondes depuis l'époque.

Plus d'informations sur cet appel système se trouve dans le page man .


0 commentaires

2
votes

comme un addendum à la réponse par les pyves ci-dessus (en utilisant x86-64 / nasm / linux), si vous souhaitez obtenir une meilleure résolution d'horloge qu'une seconde, vous pouvez syscall avec 228 au lieu de 201 pour obtenir des secondes en une 64- Variable de bits et nanosecondes supplémentaires (au-delà des secondes) dans une autre variable de 64 bits.

default rel
section .bss
    time: resq 2   ; 2 qwords for seconds and nanoseconds

section .text
    mov rax, 228   ; 228 is system call for sys_clock_gettime
    xor edi, edi   ; 0 for system clock (preferred over "mov rdi, 0")
    lea rsi, [time]
    syscall        ; [time] contains number of seconds
                   ; [time + 8] contains number of nanoseconds


1 commentaires

Notez que l'appelant la fonction Wrapper Glibc (ou appelant directement à la VDSO directement ) sera plus rapide que d'utiliser syscall - le code d'exportation du noyau + des données pour une implémentation de l'espace utilisateur de la fonction utilisant RDTSC pour interpoler depuis le dernier clock_monic_coarse tique sans jamais appeler au noyau. Mais si vous voulez juste quelque chose de simple pour l'ASM écrit à la main, alors oui, faites cela.