News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Arnaud

Should disable interrupt when using ex (sp), hl

Started by Arnaud, 19:38, 05 May 20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Arnaud

Hi,
i think i have found rare and totally random bug in my code, i solved it by disable interrupt when using ex (sp), hl

Is mandatory to disable interrupt with a "classic" use of the stack with using pop / push / ex (sp), hl simply to store data ?

Arnaud

andycadley

As long as your interrupt routine correctly manages the stack (i.e. POPs the same number of things it PUSHes), no it shouldn't be. But if you're doing something funky like abusing the stack pointer as a fast way of clearing memory then you probably don't want an interrupt routine cutting in and messing up memory you weren't expecting.

Arnaud

And for ex (sp), hl the code exchange hl with sp value which was potentialy modified in interrupt ?

andycadley

Like I say, it shouldn't matter because the effect of the ISR (aside from trashing stack memory) should be entirely transitory. Once it returns, assuming every register it uses was preserved and all PUSH/POPs match, the registers should all be in the same state as they were before it started. It's more likely that either the ISR is using registers it doesn't preserve, trashing memory that is important or some other kind of race condition that disabling interrupts is hiding.

Arnaud


GUNHED

ex (sp),hl can be a killer as soon as the next POP or RET will follow.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

andycadley

Quote from: GUNHED on 21:27, 05 May 20
ex (sp),hl can be a killer as soon as the next POP or RET will follow.
But the ISR will always PUSH a return address first and the PUSH//POP the same amount of data. The status of the stack should be unchanged once an ISR completes, regardless of whether an EX (SP), HL was done beforehand or not as the Z80 can't interrupt mid-instruction.

GUNHED

Quote from: andycadley on 22:25, 05 May 20
But the ISR will always PUSH a return address first and the PUSH//POP the same amount of data. The status of the stack should be unchanged once an ISR completes, regardless of whether an EX (SP), HL was done beforehand or not as the Z80 can't interrupt mid-instruction.

That's not the point. Imagine the following two situations f.e.:

LD DE,API_Entry
PUSH DE ;store return address
EX (SP),HL ;store
RET


or....


CALL XXX
...

XXX EX (SP),HL
...
RET


Some games have that kind of constructions.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

andycadley

Still doesn't matter.


No matter which of the instructions in that sequence is proceeded by an interrupt, the end result will be exactly the same as long as the ISR properly manages the stack.

GUNHED

Well, the RET does POP an element from the stack into SP. If this element was exchanged before, the CPU will not RETurn, instead it will jump somewhere else. Just give it a try with you assembler or choice.  :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

andycadley

I know. it doesn't change anything though.


Imagine the following code:


PUSH HL
RET


Which, effectively, jumps to HL via the stack.


Now imagine the same code, but that an interrupt occurs right between the two commands:

Before the interrupt, HL is on the top of the stack.
*interrupt occurs*
The Z80 PUSHes the return address so that becomes the top of the stack. A well behaved ISR can PUSH/POP whatever it likes and as long as the sequence is balanced it will end with the return address at the top of the stack.


Finally the ISR does a RET, popping it's return address off the stack. At this point the value of HL will once again be the value on the stack
*interrupt handling complete*


The previous code continues at the RET, which fetches HL from the stack and jumps to it.




The sequence for the interrupted code is logically the same regardless of if/when an interrupt occurs. This will always be the case as long as the following are true:


* The stack hasn't been moved to point at memory that mustn't (or can't) be written too.
* The ISR doesn't trash any registers (unless the overall system design allows it to - f.e. reserving the alternate register set for ISRs)
* There is sufficient stack space so the it doesn't clobber something else (or worse some other called code clobbers the stack) 

GUNHED

Seems we're talking slightly different topics.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Powered by SMFPacks Menu Editor Mod