1

I am trying to write assembly to detect if the present interrupt happened between two particular instructions.

I think I have it, but it's not easy for me to test, so if someone could verify I would very much appreciate it.

LDR R0, =INSTR_A ;address of first instruction
CMP LR, R0       ;are we ahead of the first?
BLO NOPE
LDR R0, =INSTR_B ;yes, address of second instr
CMP LR, R0       ;are we ahead of second?
{YEP}LO          ;no, so we're between, do {stuff}LO
{MORE STUFF}LO

Does that look right?

My concern is that I should be using LS instead of LO?

nrz
  • 10,435
  • 4
  • 39
  • 71
OJFord
  • 10,522
  • 8
  • 64
  • 98
  • Sorry, thought it was clear running in interrupt, since it's to detect where the interrupt happened. IRQ handler. No other interrupt exists, so I'll keep it simple. Comments added in a sec. – OJFord Dec 24 '13 at 04:19
  • save the lr in the isr, you can determine from that where the interrupt occurred. Otherwise you have to have some coordination between the handler and the forground to communicate with each other. – old_timer Dec 24 '13 at 14:45
  • But `LR` is already saved, to return from the ISR..? So that is what I'm doing, no? – OJFord Dec 24 '13 at 15:07
  • "I'm trying to make a contraceptive device out of barbed wire, and..." - some questions clearly need a rational explanation of why your doing something that's clearly insane to begin with.. ;-) – Brendan Dec 27 '13 at 04:36
  • Haha! Well, if interrupted between two particular instructions, my code will return an incorrect result. I want to fix the error in the IRQ. Disabling interrupts for duration of those instructions is not an option. – OJFord Dec 27 '13 at 15:19
  • 1
    An example of such a technique is in the Linux ARM kernel. The [`kuser_cmpxchg_fixup`](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/kernel/entry-armv.S#n891) does a similar thing. Each ARM process has a known page at *0xffff0000* on an ARMv5, and the routine tries to implement the *cmpxchg* quickly. However, an interrupt or data abort can destroy the *atomic* nature, so those handlers reset the PC so the code retries the instruction. It maybe helpful for you. In the Linux kernel, `#S_PC` is already corrected on exception entry (see `vector_stub`). – artless noise Dec 29 '13 at 17:37

2 Answers2

1

LR_IRQ is always address+4 of the instruction that was interrupted.

ie:

 0x00 mov r0, #0  <-- First instruction
 0x04 mov r1, #1
 0x08 mov r2, #2  <-- Interrupt occurs here, Address will be 0x0c in LR_irq not 0x08
 0x0c mov r3, #4  <-- Second instruction

I hope you can figure out what's wrong with your code now :)

sgupta
  • 1,214
  • 2
  • 15
  • 29
  • If interrupt occurs there, has #2 been moved to r2 though? – OJFord Dec 27 '13 at 15:20
  • No. writeback is aborted and you must return to that specific instruction (LR-4, 0x08 and not 0x0c as is contained in LR). – sgupta Dec 27 '13 at 15:29
  • Also, if the code that was interrupted is using thumb interworking you have to be extra careful in what you subtract from LR. Depending upon T bit in SPSR, THUMB2 32-bit instructions, you have to subtract 4 or 2 from LR of the IRQ mode. – sgupta Dec 27 '13 at 15:31
  • Thank you, I added #4 after loading address of each instruction, and tested condition `LS`. Working a treat. Thanks for helping me understand. And no thumb instructions, so luckily I don't have to consider that :) – OJFord Dec 27 '13 at 19:20
-1
LDR R0, =INSTR_A ;address of first instruction
CMP LR, R0       ;If LR < R0 (or LR - R0 underflows), set carry
BLO NOPE         ; Branch if carry set (LO = CC)
LDR R0, =INSTR_B ;yes, address of second instr
CMP LR, R0       ;are we ahead of second?
BLO YEP          ;This is what you meant?
turboscrew
  • 676
  • 4
  • 13
  • You realise that what you've done there is post my code from OP, as an answer, as though it's your own? – OJFord Dec 24 '13 at 15:05
  • If you're claiming `BLO YEP` is your added value, that's not an improvement. Doing `{stuff}LO` and `{more}LO` takes two cycles (linear with # instructions), your `BLO` takes an additional four. – OJFord Dec 24 '13 at 15:10
  • My 2c are the comments. It should be seen that the code is copy of what appears to me as the code from the original posting. (What do you mean by "my code from OP"?) Which way would yoy have done that? – turboscrew Dec 25 '13 at 00:42
  • So you want the instructions themselves included or not? I mean the LR contains the return address. In your way you (probably) should use the same conditiond for both comparisons to have symmetrical behavior. – turboscrew Dec 25 '13 at 11:24
  • My point is just that 'yes' would have sufficed, I asked if was correct, and your answer is . – OJFord Dec 26 '13 at 01:30
  • If the interrupt happens before executing the earlier "border instruction", the LR contains its address, and the branch to NOPE takes place. That is: the "border instructions" are now excluded. Think of the locations between instructions as the places. – turboscrew Dec 26 '13 at 07:22