Link to home
Start Free TrialLog in
Avatar of SADIK
SADIK

asked on

1 sec. delay loop

Hello Experts ! I need very quick help to my very easy :) question. How can I write a loop to delay appx. 1 second on a moderate Pentium IV PC. I have been searching in the forum and googling a couple of hours but couldn't find an appropriate code, or my Assembler (NASM) is not willing to compile it ! Please help.. Thanx in advance..
Avatar of joghurt
joghurt

What kind of operating system is your target? Can you handle the timer tick interrupt?
;  for approx 1 second


        mov    ax,1000  ; adjust this constant up or down as needed to get closer to 1 second

wta:     mov    cx,65000

wt:    nop
        loop   wt

         dec   ax
         jnz   wta




grg99, do you believe this will work on a P4 (as asked in the original question)? P4s have very nice stuff to optimize this.

Furthermore, this kind of looping is VERY processor-dependent: It may give you a 1 second wait on a P4 1.5 GHz, but will give you less than 450 milliseconds on a P4 3.4 GHz. Even more, on variable-speed CPUs (SpeedStep, LongRun, etc.) used in mobile computers, this loop may take 5 seconds or more because this simple loop enables the CPU to stay in the low-speed mode. [These all presume you have a loop that is not optimized off by the CPU which is clearly not the case with the above code.]

If this code runs in a multi-tasking environment, the delay may also be lengthened.

All in all, I believe that knowing the target OS we can supply him/her with a much better solution.
yes, I know.

On a DOS thru Windows NT system, from a 16-bit program, he can peek at $40:$6C which is a longint that (mostly) increments about 18.2 times a second.

In Windows, there's API's like GetTickCount that return milliseconds since bootup.

There's always RDTSC, which counts CPU clock cycles, but to get a second you have to know the CPU frequency.

something like:

Million EQU 1000000

CPUCYCLESPERSECOND     EQU      450*Million

       RDTSC
       add EAX,CPUCYCLESPERSECOND   ;  target
       adc  EDX,0                                  ; carry
      mov   ESI,EAX
      mov   EDI,EDX

LP:    RDTSC
        cmp    EDX,EDI     ; are high 32 bits right yet?
        JNE    LP              ; no

        cmp     EAX,ESI    ; hi correct, how about low
        JB      LP              ; not yet





grg99, this is exactly why I've asked for the OS in my first comment. :-) But he/she seems to forget about his/her question.
If you have to write a loop in Aseembly language, i.e. not in high level language and not using timer, what I would do for convenience is

- on any other PC with same processor frequency, using linux or windows

- write a command line tool doing a loop, and evaluating time using system calls (not interrupted by windowing system)
   (the only difference will be the task switching time, insignificant if this is the only active application)

#include <sys/time.h>
struct timeval tt;

void start() {   gettimeofday(&tt, NULL);  }
unsigned long end() {  struct timeval t;  gettimeofday (&t, NULL);  return (t.tv_sec*1000 + t.tv_usec/1000) - (tt.tv_sec*1000 + tt.tv_usec/1000); }

     int i,z;
     start ();
     for (i=z=0 ; i<10000000 ; i++) z += i;
     printf ("Took %ld ms\n", end());

Affine the 100000000 to get 1000 ms.

- once you are ok, if you used gcc to compile your program do

    gcc -S myprog.c

to get myprog.s (assembly)

E.g. on my pc it gave exactly 1000 ms. (have to ensure stack adressing is ok :)

        movl    $0, -8(%ebp)
        movl    $0, -4(%ebp)
L4:
        cmpl    $99999999, -4(%ebp)
        jle     L7
        jmp     L5
L7:
        movl    -4(%ebp), %eax
        leal    -8(%ebp), %edx
        addl    %eax, (%edx)
        leal    -4(%ebp), %eax
        incl    (%eax)
        jmp     L4
L5:
Avatar of SADIK

ASKER

Well, thank you for those quick responses.. they were really quicker than I expected.. My OS is W2K Server which will be a stand alone server running only IIS and the small program that will send some sort of signal to the parallel port by 1 sec delays.. I am quite a beginner so if you can help to write a processor free code, it'll help a lot.. I don't know how to use time ticker.. Pls. be clear and concise.. Thanx again..
Must it be in assembly?

Btw, you can call the Sleep system function from assembly. You have to link your call to "_Sleep@4", pass the desired value in ECX (the wait time in microseconds) and call into kernel32.dll. (The same applies to the "sleep" C runtime function within msvcrt.dll)
If you like this idea, we can supply you with the code.

And as another option, if you think you've find a suitable code while Googling, we can help you to get it compiled with NASM.
Then the best way is to call Sleep() as joghurt has suggested.

Avatar of SADIK

ASKER

Yes joghurt can you write down the code you mentioned ? Please make it clear for me to understand.. My current code is like this :

       PUSH DX
       MOV DX,0378H
       MOV AL,01H
       OUT DX,AL
      CALL Delay1     ;One second delay
       MOV AL,02H
       OUT DX,AL
      CALL Delay1     ;One second delay
       MOV AL,04H
       OUT DX,AL
      CALL Delay1     ;One second delay
       MOV AL,08H
       OUT DX,AL
       POP DX
       RET
       NOP

; This will loop for 1 Sec
Delay1:    ????
               ????
               ????

P.S. joghurt, do u think NASM is a good compiler? If not can u suggest an other one?
I use a commercial compiler so it's not the question of being better. (But anyways, it's better than NASM, I think.) If you are interested in free compilers only, you can find some out there, such as Go-Asm, or versions of GCC. However, I personally don't have much experience with them, except gcc on Linux. But you can find many questions here on EE asking about the best (free) compiler.
Avatar of SADIK

ASKER

Thanks joghurt.. So what about my code ??
ASKER CERTIFIED SOLUTION
Avatar of joghurt
joghurt

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Can you not just call the following?

pushl      $1
call      sleep

you can change the amount of time by changing the value you push onto stack...
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial