Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site mips.UUCP Path: utzoo!watmath!clyde!bonnie!akgua!whuxlm!harpo!decvax!decwrl!Glacier!mips!kim From: kim@mips.UUCP (Kim DeVaughn) Newsgroups: net.micro.pc Subject: Re: Clock Interrupt Screw-Up? Message-ID: <201@mips.UUCP> Date: Fri, 4-Oct-85 04:34:48 EDT Article-I.D.: mips.201 Posted: Fri Oct 4 04:34:48 1985 Date-Received: Mon, 7-Oct-85 03:03:54 EDT References: <822@gitpyr.UUCP> Organization: mips ... where RISC is a way of life Lines: 61 [...] > I have a section of assembler code which exhibits an interesting anomaly: > > The code works just fine when interrupts are disabled. However, when > interrupts are enabled the code produces the wrong results. There is > ... > number into a binary value, and back to ASCII, and then prints the result. > The result is always correct when interrupts are disabled, but about > 1 in 20 times it is wrong when interrupts are enabled. The wrong value > appears to be a random value, and appears on a random basis. The only > interrupt which should be occuring is the clock (timer) interrupt. Without seeing the code, this is purely a guess ... Sounds alot like you've been bitten by the "multiple prefixes on a string-op" feature of the 8086/8. Let's say, for example, you code: rep movs ES:byte ptr[DI],CS:[SI] to move a string. "rep" is a prefix to the "movs" instruction, but so is the "CS:" seg-reg override byte. As long as there's no interruption, this works just fine. If a rupt occurs in the middle of the move though, watch out! If a rupt had to wait until all repetitions were completed, it might have to wait quite awhile on large byte counts ... too long for some time-critical functions. To avoid this, the 8086 will recognize a rupt (assuming they are enabled, of course) after a fundemental "unit of operation" is complete. In this case, that means after a byte has been transfered, CX has been decremented, SI and DI have been incremented (or decremented), and the test for CX=0 has been performed. The problem is that the instruction pointer points to the "rep" prefix while the string-op is executing, and the "rep" prefix MUST be the prefix just prior to the string-op itself. It's the offset of the "rep" that gets pushed on the stack when a rupt comes in ... and that's where execution resumes after the rupt handler returns control via an "iret". Of course NOW the 8086's bus-unit is merrily forming source addresses using DS:SI rather than CS:SI like we thought we told it to; it never saw the CS: override prefix again. (Yes, Virginia, it *is* supposed to work that way ... like I said, it's a feature, not a bug, and yes, it is documented ... bahhhh!) Anyway, if you find any such beasties, just stick a "cli/sti" pair around the offender, and maybe send a "Thank you" note to those wonderful folk who brought you segmentation in the first place :-). Hope this helps. BTW, anyone know if this stunning example of architectural innovation is still with us in the 286? /kim "Anything free is worth what you pay for it." -- Lazarus Long -- UUCP: {decvax,ucbvax,ihnp4}!decwrl!mips!kim DDD: 415-960-1200 USPS: MIPS Computer Systems Inc, 1330 Charleston Rd, Mt View, CA 94043