Not really a great "delay" implementation. If someone were to use such a crude looping system to delay a program (and I doubt any semi-modern operating system does this) some NOP instructions would be much simpler.
Real delay operations context switch to another process or thread for a minimum of the desired amount of time. A better implementation for single-tasking systems would be something like the following pseudocode:
; we assume the realtime clock is already setup to trigger timer interrupts at a regular interval (short enough that our delay function has the desired precision)
delay:
; Assume time to delay (in timestamp ticks, converted from milliseconds elsewhere) is in ebx
RDTSC eax ; Read timestamp into ebx (not the real way to use RDSTC!)
ADD ebx, eax ; ebx now contains the timestamp coutner value of when the delay should end
.delay_loop:
CMP eax, ebx ; compare the current timestamp to the end time
JG .delay_end ; if the current time is greater than the end time, we're done
; Otherwise we wait...
HLT ; Put the processor in lower power "sleep" state
; When the timer interrupt fires (at regular intervals), the processor is woken up
RDTSC eax ; Read new timestamp counter value (not the real way to use RDSTC!)
jmp .delay_loop ; Compare again and keep waiting
.delay_end:
RET ; return from delay function