News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CpuClockSpeed

Started by skywalker, March 01, 2006, 02:03:09 PM

Previous topic - Next topic

skywalker

CpuClockSpeed assembles OK with Masm 9.0 but the program runs but never pauses for the user to hit a key.

Thanks.

MichaelW

If you are building the code that I posted as a console app, I can't see how this could happen. Here is a version that does not depend on inkey or masm32rt.inc:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .586                                ; create 32 bit code
    .model flat, stdcall                ; 32 bit memory model
    option casemap :none                ; case sensitive
 
    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\Comctl32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\oleaut32.inc
    include \masm32\include\msvcrt.inc

    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Comctl32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\shell32.lib
    includelib \masm32\lib\oleaut32.lib
    includelib \masm32\lib\msvcrt.lib

    include \masm32\macros\macros.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call CpuClockSpeed
    .IF eax
      push  eax
      push  eax
      fstp  QWORD PTR[esp]
      pop   eax
      pop   edx
      invoke crt_printf,chr$("%.2f MHz%c"),edx::eax,10
    .ENDIF 
   
    mov   eax, input(13,10,"Press enter to exit...")
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; This proc determines the CPU clock speed in MHz by counting TSC
; cycles over a one-second interval timed with the high-resolution
; performance counter. If the processor supports CPUID and RDTSC
; and the system supports a high-resolution performance counter,
; the clock speed is left on the FPU stack in ST(0) and the return
; value is non-zero. Otherwise, the return value is zero.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

CpuClockSpeed proc uses edi esi

    LOCAL pcFreq  :QWORD
    LOCAL pcCount :QWORD

    ;-----------------------------------------------------------
    ; CPUID supported if can set/clear ID flag (EFLAGS bit 21).
    ;-----------------------------------------------------------

    pushfd
    pop   edx
    pushfd
    pop   eax
    xor   eax, 200000h  ; flip ID flag
    push  eax
    popfd
    pushfd
    pop   eax
    xor   eax, edx
    jz    fail

    ;------------------------------------------------
    ; TSC supported if CPUID function 1 returns with
    ; bit 4 of EDX set.
    ;------------------------------------------------

    mov   eax, 1
    cpuid
    and   edx, 10h
    jz    fail

    invoke QueryPerformanceFrequency, ADDR pcFreq
    or    eax, eax
    jz    fail
    pushad
    invoke crt_printf,chr$("pcFreq:%I64d%c"),pcFreq,10
    popad

    invoke GetCurrentProcess
    invoke SetPriorityClass, eax, HIGH_PRIORITY_CLASS

    ;----------------------------------------------------
    ; Sync with performance counter and get start count.
    ;----------------------------------------------------

    invoke QueryPerformanceCounter, ADDR pcCount
    mov   edi, DWORD PTR pcCount
  @@:
    invoke QueryPerformanceCounter, ADDR pcCount
    cmp   edi, DWORD PTR pcCount
    je    @B

    rdtsc
    push  edx
    push  eax

    ;-----------------------------------------
    ; Calc terminal count for 1 second delay.
    ;-----------------------------------------

    mov   edi, DWORD PTR pcCount
    mov   esi, DWORD PTR pcCount + 4
    add   edi, DWORD PTR pcFreq   
    adc   esi, DWORD PTR pcFreq + 4

    ;---------------------------------------------
    ; Loop until PC count exceeds terminal count.
    ;
    ; Cannot check low-order dword for equality
    ; because PC cannot be depended on to always
    ; increment count by one.
    ;---------------------------------------------
  @@: 
    invoke QueryPerformanceCounter, ADDR pcCount
    cmp   DWORD PTR pcCount+4, esi
    jne   @B
    cmp   DWORD PTR pcCount, edi
    jb    @B   

    rdtsc
   
    pop   ecx
    sub   eax, ecx
    pop   ecx
    sbb   edx, ecx

    push  edx
    push  eax
    finit
    fild  QWORD PTR[esp]
    fld8  1000000.0
    fdiv
    add   esp, 8    ; Not necessary here, but still a good practice.

    invoke GetCurrentProcess
    invoke SetPriorityClass, eax, NORMAL_PRIORITY_CLASS

    return 1

  fail:

    return 0

CpuClockSpeed endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
eschew obfuscation