Hi,
Ok - 2 mistakes.
The first one is your 64-bit subtraction:
Code: Select all
sub eax, dword [TLow]
sub edx, dword [THigh]
This doesn't work, and should be:
Code: Select all
sub eax, dword [TLow]
sbb edx, dword [THigh]
This is a little like doing subtraction on paper and forgetting to "carry the one".
The other problem is this:
This divides the address of your TLow variable by 500000 at compile time, and then gets the value at that address - you could skip everything before this instruction and still get the same dodgy answer.
To do unsigned division (at run time) you should probably consider the DIV instruction....
For example:
Code: Select all
rdtsc ;Get a decent assembler!
mov dword [TLow], eax
mov dword [THigh], edx
mov ax,9 ;This will set up about a
call SetTimer ;500 ms delay (that will halt the
rdtsc ;Get a decent assembler!
sub eax, dword [TLow]
sbb edx, dword [THigh]
mov ebx,5000000
div ebx ;divide the 64-bit value in EDX:EAX by the value in EBX
mov dword[CPUSpeed],eax
It's also probably a good idea to round it to the nearest:
Code: Select all
rdtsc ;Get a decent assembler!
mov dword [TLow], eax
mov dword [THigh], edx
mov ax,9 ;This will set up about a
call SetTimer ;500 ms delay (that will halt the
rdtsc ;Get a decent assembler!
sub eax, dword [TLow]
sbb edx, dword [THigh]
mov ebx,5000000
div ebx ;divide the 64-bit value in EDX:EAX by the value in EBX
shr ebx,1 ;ebx = half the divisor
sub edx,ebx ;set the carry flag if the remainder is greater than half the divisor
adc eax,0 ;Round up if carry is set
mov dword[CPUSpeed],eax
I'm thinking the answer you get will change each time you boot, and could be (roughly) 10% wrong. The reason for this is you don't know how long it will be before the first IRQ occurs, and your delay will be between 439 ms and 494 ms, or between 494 ms and 549 ms.
It'll also take (roughly) half a second to measure something that will typically happen around 1 billion times per second (a 5 ms delay would be more than enough).
It'd be possible to fix both of these problems by reading a PIT timer's count, rather than waiting for an IRQ...
Cheers,
Brendan