flat assembler
Message board for the users of flat assembler.

Index > Main > emulating delay?

Author
Thread Post new topic Reply to topic
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 19 Jan 2013, 12:14
Hi there, I'm thinking how to delay programs execution w/o using any API function that any OS provide. I'm trying to do it by calculating ticks per Sleep(Windows) function and then loop for amount of ticks it took. But I'm sure I'm doing it wrong, I have no other idea how to emulate it.. Here's the code
Code:
...
rdtsc ;get tick count
mov ebx,eax
invoke Sleep, 1000 ;sleep for 1 seconds
rdtsc
sub eax,ebx ;eax = number of ticks it took.
mov ecx,eax
loop $ ;loop
nop ;(in my mind) this should be reached after 1 seconds, but nope, it does faster.    

Does anyone tried it? Thank you.
Post 19 Jan 2013, 12:14
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 19 Jan 2013, 15:59
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:57; edited 1 time in total
Post 19 Jan 2013, 15:59
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 19 Jan 2013, 16:05
I know that it's in EDX:EAX, I need only low order cause I'm not doing it on bigger number delays. Then how?
Post 19 Jan 2013, 16:05
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 19 Jan 2013, 18:12
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 21:57; edited 1 time in total
Post 19 Jan 2013, 18:12
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 19 Jan 2013, 18:45
Overflowz,

Do you want to pause program for an exact amount of time (that'll require real-time OS), or to stall execution (on a non-HT/multicore CPU) for the very same time (at least)?
Post 19 Jan 2013, 18:45
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 19 Jan 2013, 21:09
The first section of code may have fewer ticks due to lower clock inside the sleep call than the second section which will likely max the core. This also assumes loop takes one clock per instruction cycle.

Without OS calls, the best I can think of is measure a small loop and scale it against your own real time readings, with checks on rdtsc for each loop iteration until the expected count has been reached.
Post 19 Jan 2013, 21:09
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 19 Jan 2013, 21:21
Overflowz wrote:
Hi there, I'm thinking how to delay programs execution w/o using any API function that any OS provide.

What's your reason for wanting to do it this way?

Your OS has the advantage of simply not scheduling your thread for execution - which means zero CPU time wasted until it's back on the ready-list. If you try to do a delay by looping/whatever, you'll be burning a lot of CPU cycles, which is quite counter-productive.

If you're trying to do this because you need very precise delays (which Sleep() doesn't give, although ), you're Doing Things Wrong and perhaps even using a wrong OS for your task Smile

_________________
Image - carpe noctem
Post 19 Jan 2013, 21:21
View user's profile Send private message Visit poster's website Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 70
Location: Belgium
SeproMan 20 Jan 2013, 11:13
Overflowz,

a. Are you sure that Windows allows the use of the "rdtsc" instruction?
b. You do need the high dword EDX of the TSC because todays computers reach it easily.
c. When you "sub eax,ebx" you might get a negative value!

_________________
Real Address Mode.
Post 20 Jan 2013, 11:13
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 20 Jan 2013, 13:51
SeproMan wrote:
a. Are you sure that Windows allows the use of the "rdtsc" instruction?

It does - but it's not a good idea to use RDTSC for delay loops. On several AMD CPUs, the TSC is not synchronized between cores, which will give funny effects when your thread is rescheduled... and not all CPUs have a constant frequency for the TSC (because of frequency regulation).

_________________
Image - carpe noctem
Post 20 Jan 2013, 13:51
View user's profile Send private message Visit poster's website Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 20 Jan 2013, 16:18
Sorry for long reply, I'm just curious how to pause execution of program for amount of time. I just want to know it deeper, how it can be done, or like a challenge which I can't solve Very Happy
Post 20 Jan 2013, 16:18
View user's profile Send private message Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
ACP 23 Jan 2013, 07:35
If you still want to use rdtsc here is the proper way of calling it for time measurement:

Code:
cpuid
rdtsc
;rest of the code
    


It will not solve some problems mentioned already however.
Post 23 Jan 2013, 07:35
View user's profile Send private message Reply with quote
Overflowz



Joined: 03 Sep 2010
Posts: 1046
Overflowz 24 Jan 2013, 18:30
Should I believe that nobody have tried it yet?
Post 24 Jan 2013, 18:30
View user's profile Send private message Reply with quote
macgub



Joined: 11 Jan 2006
Posts: 346
Location: Poland
macgub 25 Jan 2013, 11:00
Overflowz,
have you tried it in other OS than Windows ?
Post 25 Jan 2013, 11:00
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 25 Jan 2013, 12:33
For example this:
Code:
rdtsc ;get tick count
shl rdx,32
add rdx,rax
push rdx
invoke Sleep, 1000 ;sleep for 1 seconds
rdtsc
shl rdx,32
add rax,rdx
pop rdx
sub rax,rdx
mov rcx,rax
loop $ ;each loop might take more than 1 tick (its a macroinstruction)
    

takes about 5 seconds.
Code:
; [---]
@@:
 sub rcx,1
 jne @b 
    

takes about 3 seconds and
Code:
@@:
 times 10 nop
 sub rcx,10
 jnc @b
    

<2 seconds.

When I measure Sleep, my CPU is @1.2GHz so the result is ~1.2 billion ticks.
When I start that tight loop, my CPU clocks up to 3.2GHz, but it will not finish
in 0,375 sec because loop is a macroinstruction.
You can see the time nearing 2 seconds if there are many nops in between.

http://randomascii.wordpress.com/2011/07/29/rdtsc-in-the-age-of-sandybridge/
You simply cannot trust the RDTSC.

I cannot tell you if my RDTSC will stay the same even if the CPU throttles.
Post 25 Jan 2013, 12:33
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20299
Location: In your JS exploiting you and your system
revolution 25 Jan 2013, 13:13
RDTSC is probably only useful for very short timing accuracy (if done properly). For longer timing there are many many things that can affect the reading. Some things quickly off the top of my head: task switch, interrupts, thermal limits, cache contents, previous instructions in the queue, trailing instructions in the queue, memory buffer contents, etc. etc. etc.
Post 25 Jan 2013, 13:13
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.