Is there a way to pause a program in assembly for say, 1 second, and then let it resume its normal flow? I'm programming a chat through the serial port, but for some reason, when I type a string on one of the programs, the other one does not always receive it as a single string; Sometimes it prints it as a whole, but other times it displays only one part and immediatly realizes there's more string to receive and prints it as a second string. What I'm trying to do is to stop the program for a second or so, so it can be sure that it receives the whole string and not just a part of it.
-
If you're doing it right, you should get a stream of bytes that are only displayed when you receive some sort of "end of message" byte (e.g. a newline character), and you shouldn't have any need for a pause to begin with. Your 1 second pause doesn't solve the problem. – Brendan Apr 04 '13 at 01:39
-
3Please specify CPU and OS. The answer would depend on those. In fact, please do the same for all [assembly] questions. – Seva Alekseyev Apr 04 '13 at 02:24
-
1Would it not be easier to fix your chat protocol so that string start/end can be identified when received as a byte stream? Timer bodges don't work reliably, or introduce annoying latency, or both. – Martin James Apr 05 '13 at 12:41
5 Answers
For 80x86; if the OS is something like MS-DOS or "none" then you'd want to poll the BIOS's "ticks since midnight" in a loop while doing HLT (to save power). To get the "ticks since midnight" use int 0x1A
with ah=0x00
. One second will be approximately 18 ticks. Be very careful with roll-over - if you're not careful and do "expiry_time = now + 1 second" just before midnight then you could be waiting forever, and you should do if(expiry_time >= 0x001800B0) expiry_time -= 0x001800B0
to prevent that.
If the OS is anything modern (Windows, OS X, Linux, FreeBSD, etc) then you want to tell the OS's scheduler to run other tasks for 1 second (to avoid hogging CPU time for no reason); and you'll either have to find the appropriate (OS specific) API to do that or find some sort of library to link against that does it for you.

- 35,656
- 2
- 39
- 66
-
+1 (I made once an infrared transmitter for 80386 using this technique.) The microsecond resolution interval didn't have to worry about overflows though. – Aki Suihkonen Apr 04 '13 at 03:30
-
I tried this waiting for 1 tick( aprox 55ms) and it work just fine, none of my strings are being receive in pieces anymore – Ricardo Apr 04 '13 at 05:35
I am answering not the question itself, but anyway:
Never (I mean NEVER!) use time delays for such goals! It is very, very, very bad design. The serial port communication is based on character streams. The properly designed program (regardless of the language used) must process stream without need of any time delays.

- 6,857
- 4
- 31
- 60
Yes,
use GOTO and NOPS.
or create a loop conainting nops and escape it when certain condition are met. or create a GOTO label a bunchs of nops
startover
nop
nop
nop
nop
nop
nop
nop
nop
GOTO startover // this wil run forever! you need an escape condition

- 934
- 1
- 9
- 21
-
1Every CPU has at least one assembly language (and often there's 2 or more different assembly languages for a CPU - e.g. Intel syntax vs. AT&T). Because the question doesn't say which assembly language for which CPU, "pseudo-assembly" is a good idea. `GOTO` isn't assembly, but `GOTO` exists in many languages and is very widely understood, which makes it an attractive option for "pseudo-assembly". – Brendan Apr 04 '13 at 01:34
-
what i dont understand is nop, i suppose it doesn't really do anything other than wasting time. – Ricardo Apr 04 '13 at 05:34
-
`nop` Stands for: "No Operation". It is often used for readabilities sake; mostly because it does nothing (Literally), however it does consume time and therefore can be used to delay the program... – Cartier Jun 24 '14 at 19:46
-
1You can't use NOP in that case. Because NOP need clock cycle but you don't know how many (depend on the Proc) and you don't know how long last a cycle (depend on proc frequency). If you must wait eg "2 sec" you must find a clock timer in the system and rely on it. – Peter Oct 23 '16 at 20:56
Yes, you can get the system clock, and then make a loop to check if a second has passed after you got the time...
This might help if you are on x86 assembly: https://softwareengineering.stackexchange.com/questions/134084/assembly-instructions-execution-time
Or you can make a very long loop to make the pause... the second one I don't recommend much, but it may suit your needs
It seems the problem came from buffering. Waiting can be good but you must answer the main question which is "How many times?". And in fact, you don't really know. Comonly in ASM, we use interrupt or we wait "until a flag is set". But only "waiting a certain amout of second" seems not to be the right choice (I agree 100% with johnfound!)
Suggestion: in the sender programm, buffer the data until CR/LF then send them. On receiver, wait until CR/LF to display. Also have a look at the serial buffer pointers (IN and OUT) to see position of start and end pointer which may give some info explaining what's happening.

- 1,247
- 19
- 33