[Last Call] Learn how to a build a cloud-first strategyRegister Now


1 sec. delay loop

Posted on 2004-04-14
Medium Priority
Last Modified: 2012-06-21
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..
Question by:SADIK
  • 6
  • 3
  • 3
  • +5

Expert Comment

ID: 10823399
What kind of operating system is your target? Can you handle the timer tick interrupt?
LVL 22

Expert Comment

ID: 10824410
;  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


Expert Comment

ID: 10826952
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.
[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

LVL 22

Expert Comment

ID: 10827176
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


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

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

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


Expert Comment

ID: 10827228
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.
LVL 10

Expert Comment

ID: 10829666
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)
        cmpl    $99999999, -4(%ebp)
        jle     L7
        jmp     L5
        movl    -4(%ebp), %eax
        leal    -8(%ebp), %edx
        addl    %eax, (%edx)
        leal    -4(%ebp), %eax
        incl    (%eax)
        jmp     L4

Author Comment

ID: 10830761
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..

Expert Comment

ID: 10831325
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.
LVL 22

Expert Comment

ID: 10832088
Then the best way is to call Sleep() as joghurt has suggested.


Author Comment

ID: 10833238
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

; 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?

Expert Comment

ID: 10836114
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.

Author Comment

ID: 10840721
Thanks joghurt.. So what about my code ??

Accepted Solution

joghurt earned 400 total points
ID: 10845542
There's a tutorial about calling WinAPI functions from assembly:
You can also get some help from here:
(They are for MASM but I think you can get the idea from there for NASM).

The function you need to call is "Sleep" and it's in kernel32.dll.
LVL 49

Assisted Solution

DanRollins earned 400 total points
ID: 10973897
>>   MOV DX,0378H
>>   MOV AL,01H
>>   OUT DX,AL

Have you tried this?  With Windows, the OUT instruction is a protected opcode.  Generally, only device drivers talk directly to the hardware this way.

From that code, it appears that you are sending data to the LPT1 printer port.  It may make more sense to avoid ASM altogether and use C++ code to access Win32 API functions to do that.

-- Dan

Assisted Solution

FST earned 400 total points
ID: 11023833
If you want a delay, dont use the loops by counting up to some number because delay always changes with speed of the processor.
Use the system time:

mov bx,0
mov ah,2ch
int 21h
mov cl,dh
push cx
mov ah,2ch
int 21h
pop cx
dec dh
cmp dh,cl
jng L1

Ok this routine always delays 1~2 sec.
If you delete the line "dec dh", then it waits 0~1 sec.
Hope you find it usable..
(Bu arada Türkiye'den misin?) :)


Expert Comment

ID: 11060171
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...

Assisted Solution

keteracel earned 400 total points
ID: 11060766
in windows you'll need to push the number of milliseconds you want e.g.

pushl      $1000
call         sleep

Assisted Solution

Dawaffleman earned 400 total points
ID: 11064786
i wrote a program for this just the other day....this uses the system clock so it should be pretty accurate
i used tasm 5.1 (i think) to assemble this, it should be realitivly easy to convert:

.model medium
.386                      ;80386 instruction set
.stack 100h            ;256 bytes
.data                     ;Data segment same as:  segment para public 'data'

timer        dw  ?      ;hold initial time
time         dw  1h     ;time= 1 second
time18      dw  ?       ; this holds the computed seconds which have been translated into ticks
ticks         dw  0h      ; ticks-can be used to time less than a second, normally 18.2 ticks in a second

.code                       ; segment para public 'code'

;--------Time delay procedure-----------

    ;Purpose:  waits specified time in seconds + ticks
    ;IN:          TIME variable with time in seconds
    ;              TICKS variable with ticks (18.2 ticks per second)
    ;OUT:       Nothing

timedelay proc

mov  ax,time                 ;load ax with time in seconds
mov  cx,18                    ;get ready to multiply ax by cx
mul   cx                        ;ax now = time * 18
mov   time18,ax            ;put in appropriatly named variable
cmp   ticks,0h                ;this will add ticks to seconds if there is any
jne    settick                  ;small jump and back if we need to add ticks in
xor    ax,ax                    ;ax=0
int     1ah                      ;TIMER intterupt- gets time elapsed since midnight stores them to  cx:dx
mov   timer,dx               ;put initial time into timer variable (we only need dx cause its a short time measure)
xor     ax,ax                   ;ax=0  just precautions
xor     dx,dx                   ;dx=0
xor     cx,cx                   ;cx=0
int      1ah                     ;TIMER intterupt- gets time elapsed since midnight stores them to  cx:dx
sub     dx,[timer]           ;has the new time in dx and sees it original time-new time = time you want to wait
cmp    dx,[time18]         ;compares total elapsed ticks to your wanted time
jne     timeit                  ;if its not equal then loop back and wait till it is
jmp    endtimedelay       ;if it is equal jump to exit procedure

add     ax,ticks               ;adds ticks to the seconds
mov    time18,ax            ;moves it to appropriate variable
jmp    getinit                 ;jump back to finish timing

ret                               ;pop cs:ip and return to code
endp                            ;end procedure
;-----------------------end of time delay procedure-----------------


mov     time,1h             ;move 1 second to the time you want to wait variable
mov     ticks,0h             ;dont need any ticks (you could use 18 ihere nstead of 1 in the seconds variable (TIME)
call      timedelay          ;call procedure to wait timedelay

mov      ax,4c00h          ; get ready to terminate program (dont need this to run time delay proc, only to exit program)
int        21h                  ; call DOS intterupt- terminate program
end      start                 ; the end

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Tech giants such as Amazon and Google have sold Alexa and Echo to such an extent that they have become household names. And soon they are expected to be used by commoners in their homes, ordering takeout, picking out a song, answering trivia questio…
Exchange administrators are always vigilant about Exchange crashes and disasters that are possible any time. It is quite essential to identify the symptoms of a possible Exchange issue and be prepared with a proper recovery plan. There are multiple…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Screencast - Getting to Know the Pipeline
Suggested Courses

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question