Reputation: 55
I'm trying to understand the assembly code in my book for SVC. I get everything until the LDRH part.
SVC_Handler PROC
EXPORT SVC_Handler
CPSID I
PUSH {r4-r8, lr}
MRS r7, psp
LDR r8,[r7, #24] ; gets SVC instruction address from PC
LDRH r8,[r8, #-2] ;How come it's -2?
BIC r8,r8,#0xFF00
....
The book uses the PC pushed onto the stack to get the SVC instruction. What confuses me is that the book says PC points to the SVC instruction already before entering the SVC_Handler. Is this true, and if it is why is there a -2? If it's PC-2, wouldn't that get the instruction before SVC? Since the SVC instruction is Thumb, is it PC-2 because the next instruction (after PC update) is actually after the SVC instruction? Here's a drawing of how I'm visualizing it. I'm using a TM4C123GX, Cortex M4. Thanks!
Upvotes: 0
Views: 1631
Reputation: 71546
as pointed it out is very typical for the program counter during the execution of an instruction to point at the next instruction, if you go back to a linear many clocks per instruction approach it has to fetch everything using the pc as the address into memory it cant start executing or at least complete until all the parts of the instruction are fetched. arms pc is fake at this point, but the fakeness makes sense. if you read the manual it tells you the specific instruction to return which for say the arm instruction set is to subtract 4 from the link register to re-run the instruction. which for arm sized is one instruction. For thumb or classic thumb instructions it is 16 bits or two bytes.
Being a cortex-m you are safe in that it appears there is only one thumb instruction encoding for svc (there isnt a thumb-2 extension so far as I can see) so you can work back to extract the encoded value. Not on a cortex-m though you have thumb and arm and it is difficult at best to determine what mode you were in how far back to go to try to find the encoded immediate, pretty much not worth it, instead use a register to indicate the function not an encoding in the instruction, and or make a system level rule that you must always svc using one of the encodings.
all they are doing here is backing up to the current instruction and the extracting the immediate from the instruction.
Upvotes: 1
Reputation: 881783
Many architectures will, when transferring execution (calling a function or servicing an interrupt), place the address of the next instruction on to the stack so that a return will go back there.
This is almost certainly what's happening here, which is why you subtract the two to get the address of the code that caused this transfer.
The only question then is why the comments seem to be wrong which will be immediately obvious once you restructure them:
MRS r7, psp
; Gets SVC instruction address from stack.
LDR r8,[r7, #24]
LDRH r8,[r8, #-2]
; Carry on with other stuff.
In other words, the comment applies to the two lines, not just the first. The first will give you the address of the instruction you will return to, the second will adjust that to reference the calling instruction.
Upvotes: 1