Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Questions on the RDTSC instruction and Memory and/or far calls

Processor: AMD ( Semipron 2800+ )? 2.00 Ghz
OS: MS-Dos

First Question:

Does the rdtsc instruction count cycles like the cycles given in
Apendix D of Art of Asemmbly? If not, how can if find the aprox. time
of on tick. Is very accurate? (meaning could a program that i'm trying to time stop the counter ?)

Second Question:
I'm makeing a program that takes 3 files, 1st is startup code, 2nd is code to be timed, 3rd is cleanup code. Then load them in the mem after CS+codesize or SS which ever is greater. Is this mem that i'm using ok?
I've read in A of A that in MS-Dos all the mem after you program is reserved for you use. is that correct?

This is the code i am using the find the mem to load the files into.



mov ax, ss
mov bx, cs
cmp ax, bx
ja .usess

mov bx, endofcode-startcode
shr bx, 4
add ax, bx
.usess:

inc ax
cmp ax, 0a000h
jae outofmem



the file is loaded at GS:00. ( GS is initalize to SS+1 or (CS+codesize)+1 whichever is greater )

then this code calculates the size of the file and determines where to put the next one.


; bx = filesize
; gs = freemem segment

shr bx, 4
inc bx

mov ax, gs
add ax, bx
mov gs, ax




Third Question:

Then i call the startup file, inititilze the timer call the code to be timed, record the time elapased, call the cleanup file.

The call is 'Call dword [CS:codepointer]' which contains offset of 0 in the first word and the seg of the code in the second word.

This seems to work becuase the code works perfectly the fisrt time.
but when i try to run the timer again, without modifyin the
'[CS:codepointer]', it lands somewhere nere the end of the intended code ( or at least that's where the program dies because of the 'bytes at CS:IP' dump that happens when it dies). I know that the
'[CS:codepointer]' is not being modifed because i print it on the sceen just before calling it. I'm stumped. I'd appreciate any help/comments/suggestion on these topics

Thanks
Peter

Sorry about the alingment of the comments, etc.
but I don't know how to use the tabs key in the edit box, it skips to the next item on the web page rather then inserting a the tab char.

This is the code that runs the main loop.



dotime:

startup ; load ds and es with cs

mov di, 0
mov cx, 80*4
zeroscrn ; clears cx char of screen

again:
mov di, 160*3


mov eax, [CS:startfile] ; lp to startup code
dispeax ; prints eax

mov si, spcstr
mov ah,dcolor
printmsg ; print some spaces

mov eax, [CS:timefile] ; lp to code to be timed
dispeax ; prints eax


mov si, spcmsg
mov ah,dcolor
printmsg ; print some spaces

mov eax, [CS:cleanupfile] ; lp to cleanup code
dispeax ; prints eax


mov ah, dcolor
mov si, addrsmsg ; asks to continue after viewing addrs
mov di, 0
printmsg

.badkey:
getkey
or al, lower_case
cmp al, 'y'
je .continue
cmp al, 'n'
je .skip ; skips timing files
jmp .badkey

.continue:
mov di, 0
mov cx, 160
zeroscrn ; clears prompt

mov di, 160*3
mov cx, 160
zeroscrn ; clears pointer to files

call dword [CS:startfile] ; works on the first try :)

times 10h nop ; seem to make timing more accurate by waiting.

timer tm ; starts timer

call dword [CS:timefile] ; works on the first try :)

timerend tm,[CS:overhead] ; stops timer and subs the overhead
; needed to start the timer and stop it

call dword [CS:cleanupfile] ; works on the first tyr :)

.skip:
mov ax, cs
mov ds, ax ; load ds with cs
mov es, ax ; load es with cs




mov si, timemsg
mov di, 0
mov ah, dcolor
printmsg

mov eax, [CS:tm]
dispeax
mov eax, [CS:tm+4]
dispeax

mov si, againmsg
mov di, 160
mov ah, dcolor
printmsg
dokey:
getkey ; waits for key

cmp ah, 03bh ; process keystroke
je calibrate ; .................
cmp ah, 03Ch ; .................
je getfiles ; .................
cmp ah, 01h ; .................
je Exit ; .................
cmp ah, 1ch ; .................
je again ; .................
jmp dokey ; .................

Exit:
exit 00h








Comments

  • jeffleydajeffleyda Posts: 390Member
    : Processor: AMD ( Semipron 2800+ )? 2.00 Ghz
    : OS: MS-Dos
    :
    : First Question:
    :
    : Does the rdtsc instruction count cycles like the cycles given in
    : Apendix D of Art of Asemmbly? If not, how can if find the aprox. time
    : of on tick. Is very accurate? (meaning could a program that i'm trying to time stop the counter ?)
    :

    Not sure what's in apendix D of AOA references, but the rdtsc instruction merely counts the number of clock cycles your CPU has executed since it was last reset. With a 2Ghz machine, it should take 4 seconds to go from 0 to FFFFFFFF. The accuracy is very, very precise.
    (note, it's a 64bit counter, so overflowing 32bits in 4 seconds still leaves plenty of room for counting)

    The counter cannot be stopped, ever, only read.



    : Second Question:
    : I'm makeing a program that takes 3 files, 1st is startup code, 2nd is code to be timed, 3rd is cleanup code. Then load them in the mem after CS+codesize or SS which ever is greater. Is this mem that i'm using ok?
    : I've read in A of A that in MS-Dos all the mem after you program is reserved for you use. is that correct?

    yes. When loading a .COM file, all available DOS memory is given to it. Provided you're not overwriting DOS itself, you should be able to write anything and not have to worry about clobbering anything.
    .EXE files load differently. There's a value in the .exe header that describes how much memory the program gets. Luckily, almost all compilers just jam that value to FFFF, so you get all available memory like a .COM file does.
    DOS usually loads low in memory, so if you start writing from your programs CS up to 9F00, you should be safe. (maybe not up that high)


    Sorry, I don't have the time to help with your other ?'s at the moment, but thought I'd answer your first 2 since no one else has.

    -jeff!
  • Ptr_082004Ptr_082004 Posts: 31Member
    Thank you for replying!!

    One problem:

    When i put 16 nops in a pre-calibrated loop it still reads zero. But i
    thought the nop was at least one cycle. Does the RDTSC really count cycles?

    Peter
  • jeffleydajeffleyda Posts: 390Member
    : Thank you for replying!!
    :
    : One problem:
    :
    : When i put 16 nops in a pre-calibrated loop it still reads zero. But i
    : thought the nop was at least one cycle. Does the RDTSC really count cycles?
    :
    : Peter
    :
    RDTSC counts CPU clock cycles, not instruction cycles. What it is counting is completely independant of what you're trying to measure.
    IIRC, NOPs are thrown away by the CPU as they come down the pipeline anyway, so they would effectively be 0 instruction cycles.

    Just performing 2 RDTSC instructions in a row should get you some amount of timing information. Here's what I did in debug:

    [code]
    C:>debug32
    Debug32 - Version 1.0 - Copyright (C) Larson Computing 1994

    CPU = ?86, Virtual 8086 Mode, Id/Step = 0F29, A20 enabled
    -a
    22D9:0100 0F31 rdtsc
    22D9:0102 668BD8 mov ebx, eax
    22D9:0105 668BCA mov ecx, edx
    22D9:0108 0F31 rdtsc
    22D9:010A CC int 3
    22D9:010B
    -g
    EAX=90D3944A EBX=90D393F2 ECX=000C3E48 EDX=000C3E48 EBP=00000000
    ESI=00000000 EDI=00000000 FS=22D9 GS=22D9 SS=22D9 ESP=00010000
    DS=22D9 ES=22D9 CS=22D9 EIP=0000010A NV UP DI PL NZ NA PO NC
    22D9:010A CC INT 3

    [/code]

    so:
    000c3e4890d3944a-000c3e4890d393f2 = 58h

    58h CPU clocks, just to save 2 values and read the timestamp again. I'm running 2.8GHz (I'm running under winXP at the moment, so there is some overhead I'm sure)

    How this works out to instruction cycles vs. clock cycles is geekier than I want to get. ;)

    So, if you were able to know the CPU speed, you should be able to determine the actual speed any set of instructions take to execute by measuring the start and stop time, then calculate it against the known cpu speed.

    -jeff!



Sign In or Register to comment.