; ; This program reads the processor's 64-bit ; cycle count register using the RDTSC instruction ; and sends it to STDOUT as a 16-byte hex number. ; If there's an error, zeros are displayed on the ; screen. Written by Zsolt Nagy Perge in Nov. 2018, ; Pensacola, Florida. ; Compiled with Borland TASM 3.2. ; This program runs in DOS mode. CODE SEGMENT ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE ORG 0100h CPUID EQU DB 15, 162 ; CPUID instruction opcode RDTSC EQU DB 15, 49 ; RDTSC instruction opcode ENTRY: MOV AX,CS MOV ES,AX ; Just in case... MOV DS,AX ; Just in case... ; If any arguments were provided, then we display the ; program description. Otherwise, if there are no ; parameters, then we run the program. MOV SI,0081h ; Arguments ptr MOV CX,SI DEC CX Cont: CLD LODSB LOOP Next ; Process no more than 128 bytes JMP Begin Next: CMP AL,0Dh ; End of argument? JE Begin CMP AL,32 JBE Cont ; Jump if whitespace ; If ANY argument is provided regardless of ; what it is, we display the program description ; and terminate the program. MOV DX,OFFSET ABOUT JMP Print_AND_Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Begin: ; Test processor. Make sure it's a 386 or higher. ; This code to identify the various processors was ; written by Dominik Freche in March 26, 1995 ; and I just copied it. .8086 PUSHF POP BX AND BH,0FH PUSH BX POPF PUSHF POP CX AND CH,0F0H CMP CH,0F0H JE ERROR ; 8086 or below 80286 OR BH,0F0H PUSH BX POPF PUSHF POP CX AND CH,0F0H JNE I386 ERROR: JMP OLDPC ; 80286 detected. I386: .386 MOV EBX,ESP AND ESP,0FFFCH PUSHFD POP EDX MOV ECX,EDX XOR EDX,040000H PUSH EDX POPFD PUSHFD POP EDX PUSH ECX POPFD XOR EDX,ECX AND EDX,040000H ; Test Alignment Check Bit MOV ESP,EBX JZ ERROR ; 80386 detected. .486 PUSHFD POP EDX MOV ECX,EDX XOR EDX,0200000H PUSH EDX POPFD PUSHFD POP EDX PUSH ECX POPFD XOR EDX,ECX ; Test ID Bit JZ ERROR ; 80486 detected. ; Okay, now that we have established that we're ; dealing with a fairly "modern" computer, ; let's run the CPUID instruction to see if the ; RDTSC instruction is available on this machine. XOR EAX,EAX NOP CPUID CMP EAX,80000001h JA ERROR ; Can't even check. XOR EAX,EAX INC EAX NOP CPUID TEST EDX,4 JE ERROR ; RDTSC is not available! ; Now, let's see if we could execute ; the RDTSC instruction without any issues. ; MOV EAX,CR4 DB 15, 32, 224 TEST EAX,4 JNZ CANTDOIT ; RDTSC is privileged. ; It seems that the RDTSC instruction is safe to ; execute on this system and won't cause a crash. NOP RDTSC ; The following is for debugging purposes only: ; MOV EAX,22334455h ; MOV EDX,778899CCh ; Save EAX:EDX to where this program began. ; We're essentially overwriting ourselves here, ; but that's okay. We're not going back anyway! MOV DI,OFFSET ENTRY MOV [DI],EAX MOV [DI+4],EDX ; Now we just have to convert the 8-byte code ; located at [CS:0100] to hex format. ; And we're going to write the hex digits ; right after the 8-byte binary code. MOV CX,8 MOV DI,OFFSET ENTRY + 8 MOV SI,DI DEC SI MOV DX,DI Convert: STD LODSB CALL toHex CLD STOSW LOOP Convert ; Conversion is now done. ; Now, let's insert a $ sign at the end of this ; hex string, so DOS PRINT knows where to stop. MOV AL,'$' STOSB Print_AND_Exit: MOV AH,9 INT 21h ; Print it! MOV AX,04C00h INT 21h ; Exit 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CANTDOIT: OLDPC: MOV DX,OFFSET ZERO JMP Print_AND_Exit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Converts a number to hex format. ; ; AL <-- Binary number ; AX --> Hex number representation ; toHex: PUSHF PUSH BX PUSH CX MOV AH,AL AND AL,00Fh MOV BX,OFFSET HEX XLAT XCHG AH,AL MOV CL,4 SHR AL,CL XLAT POP CX POP BX POPF RET HEX DB "0123456789ABCDEF" ZERO DB "0000000000000000$" ABOUT DB 10, 13, "RDTSC.COM - Read x86 Time Stamp Counter" DB 10, 13, "Written by Zsolt Nagy Perge in Nov. 2018, Pensacola, Florida." DB 10, 13, " Compiled with Borland TASM 3.2." DB 10, 13 DB 10, 13, "This program reads the processor's 64-bit cycle count register using" DB 10, 13, "the RDTSC instruction and sends it to STDOUT as a 16-byte hex number." DB 10, 13, "If there's an error, you'll see 16 zeros on the screen." DB 10, 13 DB 10, 13, " Usage: RDTSC [/?]", 10, 13, 10, 13, 36 CODE ENDS END ENTRY