flat assembler
Message board for the users of flat assembler.
Index
> High Level Languages > manipulating the Real-Time Clock (RTC) x64 |
Author |
|
macomics 25 Jul 2024, 07:23
zkykernel wrote: pushad pushfd Save and restore rflags with pushfq and popfq If you are going to rewrite the assembly language code, then this command may not be necessary. You just need to create your own prologue and epilogue for the function. zkykernel wrote:
By reading directly, you can get into a situation where the first reading was before switching tasks, and the second after. If the core/processor that executes the task is changed at the same time, then you will read the wrong value for the second time. There is a function QueryPerformanceCounter/QueryPerformanceFrequency. |
|||
25 Jul 2024, 07:23 |
|
zkykernel 25 Jul 2024, 14:26
macomics wrote:
the address Code: PHYSICAL_ADDRESS port70PhysicalAddress; port70PhysicalAddress.QuadPart = 0x70; // Translate the bus address to a virtual address PHYSICAL_ADDRESS translatedAddress; if (!BusTranslateBusAddress(Internal, 0, port70PhysicalAddress, NULL, &translatedAddress)) { DbgPrint("Failed to translate bus address for port 0x70\n"); return STATUS_UNSUCCESSFUL; } // Map the translated address to a virtual address space port70MappedAddress = (PUCHAR)MmMapIoSpace(translatedAddress, 2, MmNonCached); // map 2 bytes to cover both 0x70 and 0x71 if (!port70MappedAddress) { DbgPrint("Failed to map I/O space for port 0x70\n"); return STATUS_UNSUCCESSFUL; } // Call the function to read the CPU clock DWORD cpuClock = GetCPUClock(); DbgPrint("CPU Clock: %lu\n", cpuClock); Code: DWORD GetCPUClock() { DWORD T_eax_; DWORD T_edx_; __asm { pushad pushfd cli } // Write to port 0x70 and read from port 0x71 using mapped address WRITE_PORT_UCHAR(port70MappedAddress, 0x0b); UCHAR bl = READ_PORT_UCHAR(port70MappedAddress + 1); WRITE_PORT_UCHAR(port70MappedAddress, 0x0b); UCHAR al = bl | 0x04; WRITE_PORT_UCHAR(port70MappedAddress + 1, al); while (READ_PORT_UCHAR(port70MappedAddress + 1) >= 0x38) { WRITE_PORT_UCHAR(port70MappedAddress, 0x00); } bl = READ_PORT_UCHAR(port70MappedAddress + 1); do { WRITE_PORT_UCHAR(port70MappedAddress, 0x00); } while (READ_PORT_UCHAR(port70MappedAddress + 1) <= bl); bl = READ_PORT_UCHAR(port70MappedAddress + 1); __asm { rdtsc mov T_eax_, eax mov T_edx_, edx } while (READ_PORT_UCHAR(port70MappedAddress + 1) == bl) { WRITE_PORT_UCHAR(port70MappedAddress, 0x00); } __asm { rdtsc sti sub eax, T_eax_ sub edx, T_edx_ add eax, edx mov T_eax_, eax } // Restore original state WRITE_PORT_UCHAR(port70MappedAddress, 0x0b); bl = READ_PORT_UCHAR(port70MappedAddress + 1); WRITE_PORT_UCHAR(port70MappedAddress, 0x0b); al = bl & 0xFB; // 0xFB is 11111011b in binary WRITE_PORT_UCHAR(port70MappedAddress + 1, al); __asm { popfd popad } return T_eax_; } |
|||
25 Jul 2024, 14:26 |
|
uu 25 Jul 2024, 19:15
What is the difference between RTC and TSC?
TSC is calculated after using CPUID instruction.
Last edited by uu on 26 Jul 2024, 06:47; edited 1 time in total |
||||||||||
25 Jul 2024, 19:15 |
|
revolution 25 Jul 2024, 19:24
RTC = Real Time Clock. Counts seconds, minutes, hours, etc. Not sensitive to CPU or Mobo power/clocking states. Low resolution.
TSC = Time Stamp Counter. Counts CPU clock cycles*. Reset to zero each time the system it started. Sensitive to any changes of system speed/timing. Can be a different value for each core the code runs on. High resolution. * even worse in many modern CPUs it doesn't even really count CPU clock cycles, read the specs to see what your CPUs do. |
|||
25 Jul 2024, 19:24 |
|
uu 25 Jul 2024, 20:01
revolution wrote: RTC = Real Time Clock. Counts seconds, minutes, hours, etc. Not sensitive to CPU or Mobo power/clocking states. Low resolution. Thanks for your explanation. |
|||
25 Jul 2024, 20:01 |
|
zkykernel 28 Jul 2024, 07:22
i did it !!!! SO HAPPY
|
|||
28 Jul 2024, 07:22 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.