Hi, 1) below is an assembly question with the answers in red. I am trying to find out where the numbers 3, 4, 16/4, and 16 came from. I understand they are from intel for the IA32 chipset. But I can't find any table that shows where to get these numbers. Anyone know?
2) Is the CLKS formula in the answers something standard? How do I know to use 4, 28, 16 and 16 in the formula? I have 15 assembly books that do not have this in it, and I can't find anything on the internet.

Help is appreciated

Thx, larissalle

Problem: For the following software time delay routine:

.data
Time1 WORD 3000h

.code CLKS
Delay1 PROC
mov dx, Time1 4
dly1:
dec dx 3
nop 3
nop 3
nop 3
jnz dly1 16/4
ret 16
Delay1 ENDP

... Perform the following operations:
(1) Write the # CLKS equation.
(2) For a clock frequency = 10 MHz, calculate the time delay for the entire PROC at the given DX value.
(3) What values of DX would provide the minimum and maximum time delays, and what times would they correspond to at the 10 MHz frequency?

Answers:
(1) # CLKS = 4 + 28(DX-1) + 16 + 16
= 28(DX-1) + 36 = 28DX + 8

(2) TE = 100ns * [28(12288) + 8]
= 100ns * [344072] = 34.4 milliseconds

(3) For minimum time, DX = 1 corresponding to one pass through the instructions without any loops.
TE = 100ns * [36] = 3.6 microseconds

For maximum time, DX = 0 which corresponds to a count of 65, 536.
TE = 100ns * [28(65,536) + 8] = 183.5 milliseconds

Sorry, in just a few words I have to say this calculation is bullshit.
You can not use this kind of calculation for a serious matter.
And its code is very very old.
This is the reason you won't find any code in your assembler books.

First to describe what this code about:

Somebody wrote this to let the processor do something and guess (this is a nice description of this silly code) how much time he will need for this. This can not work because processors are different in speed. AND the time the processor needs for any instruction is model dependent, not only speed dependent.

This code must be for very old processor 8086 or 8088. The "28" in your calculation is the time for execution of all code in the loop. So one NOP has 3 microops, one jmp conditional has 16 microops and dec register has 3 microops. One microop is one time cycle depending on CPU speed. So 3xNOP=9 plus 16 plus 3 = 28. The rest microops before and after loop you can forget.

The next point is, that somebody calculated that one microop or one cycle of CPU is 100ns (nanoseconds). So somebody think your processor uses 10 MHz. Today CPU frequency is maybe 2 GHz (2000 MHz) or more BUT depend on the computer. Could be 1 GHz for older models or 3 GHz for newer models.

But the fact is, that a newer processor PENTIUM needs only 1 microop for a NOP, 1 for jump conditional and 1 for decrement register. So code is about 10 times faster on a pentium for same frequency. If you have 80286, 80386 or 80486 execution time of the loop is between 3 and 28 microops or CPU cycles. Maybe you understand why I said in first sentence this code is bullshit.

The first question is how long do you need your time delay (more than one microsecond or more than one millisecond) and what you need to do this.

One easy method is to call int 15h (TSR interrupt) with following input:
cx:dx registerpair holds value to wait for in microseconds. To wait one second you have to wait 1000000 microseconds. The following code calls int15h and will return after int after specified amount of time. I can not say something about granularity about this interrupt, this is BIOS and PC model dependent. But to wait lets say one or more milliseconds this is a good solution.

mov cx,000fh
        mov dx,4240h
        mov ah,086h
        int 15h

000f4240 (hex) is 1000000

A method for a more fine timer (in nanoseconds) you could use the rdtsc instruction, available on all pentium CPUs. rdtsc reads a CPU internal timer into edx:eax (qword or 8 bytes). This register is reset on CPU reset and counts all cycles till reset. If you have a 2 GHz CPU, this internal register is incremented by 2000000000 every second or in hex 0000000077359400. This timer can be used let say something about 100 years after last reset of CPU (dependend on exact CPU frequency).
The following code reads internal real time stamp counter (rdtsc) and puts value in timer.

code sample:

timer dq 0

rdtsc
mov dword [timer],eax
mov dword [timer+4],edx

For a serious calculation you have to hook int 1ch (timer interrupt, called every 18,2 seconds) and have to read timer for at least one full timer cycle and multiply this by 18,2 to get the cpu cycles per second. With this code you can determine CPU speed. In fact this value is calculated with the PC system timer which has a frequency of 1,193,180 MHz. This value is diveded by 65536 (10000h).
So the exact value for one timer tick is 0,05492550 seconds which is about 55 milliseconds or 18,2 times per second.

For a small timer with value of one microsecond or less you could write a code which reads rdtsc, add the cycles you want to wait and in a loop call rdtsc and compare with your calculated value. Here you can get very near to 100 nanoseconds or less or at least 1 microsecond.

But a new problem since INTEL developped speed step technology. This technology reduces power consumption by decreasing voltage and frequency of CPU. This could produce false values or you have to update your time calculations many times. In most cases speed step technology is not often used for normal PCs, mainly for notebooks and netbooks but can be used either in battery mode or in power line mode.

So not so easy but I think I gave you enough tipps and informations for producing your own code.
;-)

Edited 6 Years Ago by coffeeuncle: n/a

Hi, 1) below is an assembly question with the answers in red. I am trying to find out where the numbers 3, 4, 16/4, and 16 came from. I understand they are from intel for the IA32 chipset. But I can't find any table that shows where to get these numbers. Anyone know?
2) Is the CLKS formula in the answers something standard? How do I know to use 4, 28, 16 and 16 in the formula? I have 15 assembly books that do not have this in it, and I can't find anything on the internet.

Help is appreciated

Thx, larissalle

Problem: For the following software time delay routine:

.data
Time1 WORD 3000h

.code CLKS
Delay1 PROC
mov dx, Time1 4
dly1:
dec dx 3
nop 3
nop 3
nop 3
jnz dly1 16/4
ret 16
Delay1 ENDP

... Perform the following operations:
(1) Write the # CLKS equation.
(2) For a clock frequency = 10 MHz, calculate the time delay for the entire PROC at the given DX value.
(3) What values of DX would provide the minimum and maximum time delays, and what times would they correspond to at the 10 MHz frequency?

Answers:
(1) # CLKS = 4 + 28(DX-1) + 16 + 16
= 28(DX-1) + 36 = 28DX + 8

(2) TE = 100ns * [28(12288) + 8]
= 100ns * [344072] = 34.4 milliseconds

(3) For minimum time, DX = 1 corresponding to one pass through the instructions without any loops.
TE = 100ns * [36] = 3.6 microseconds

For maximum time, DX = 0 which corresponds to a count of 65, 536.
TE = 100ns * [28(65,536) + 8] = 183.5 milliseconds

Thank you very much! This was very helpful.

i guess the max dx value is FFFFH that is (DX-1)= 65534.
Since DX is 16 bit register. it cannot be 65536 i e 10000H.

just a thought.

This article has been dead for over six months. Start a new discussion instead.