Why is r12 designated as scratch register according to the ARM Procedure Call Standard? It sits right between two groups of preserved registers: r4-r11 and sp-lr-pc. Why not make r0-r4 temporary and all else preserved?
-
3What would make your suggestion preferable? Downvote may have been because this question doesn't demonstrate much research - so it's hard to answer well. – Sean Houlihane Jul 27 '17 at 20:17
-
1I see a lots of down votes for new people try to understand and learn about new things. I see the down votes as a discouragement, and not helpful. – bstipe Jul 27 '17 at 20:55
-
@SeanHoulihane I am learning ARM assembly and I am trying to understand the reasoning behind the decision to not make r12 a preserved register, while r4-r11 and r13-r15 are preserved. – Andrey Portnoy Jul 27 '17 at 20:56
-
@bstipe Thank you! I feel like commenting is always better than anonymous, silent downvoting. – Andrey Portnoy Jul 27 '17 at 21:00
-
I am just curious - what is the point of ARM assembler learning. It is optimized for the C compilers and I bet that your assembler code will be worse than the C compiler generated one. It is good to know some basics & instructions you may want to inline for some reasons, but I cant imagine anyone writing any serious software in the ARM assembler. – 0___________ Jul 27 '17 at 21:41
-
4@bstipe people downvote because OP was not even to ask google. The very first result is: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf. So the downvote is not for the question but for beginners laziness. I did not downvote but I understand the reason. – 0___________ Jul 27 '17 at 21:46
-
1@PeterJ The point is to learn how processors work, and ARM processors in particular. I am not programming a Mars rover, just trying to learn. – Andrey Portnoy Jul 27 '17 at 21:51
-
The why the eabi authors chose to designated r12 as scratch has nothing to do with learning assembly language programming nor does it have anything to do with learning arm processors specifically. If we sat down and anaylyzed every meal you have had for a year, why did you have this for lunch this day why did you have this for dinner that day. Some might have had a reason beyond just because but to some extent there is going to be a lot of just because or why that burger joint vs this other one that you also like. they could have chosen any one of several for these tasks...all equally good. – old_timer Jul 27 '17 at 23:30
-
@old_timer To me, it does. I want to learn beyond "just because", that's why I asked this question. I'm really grateful for your input. – Andrey Portnoy Jul 28 '17 at 00:11
-
@0___________ The link is now dead now. Good thing [google](https://www.google.com/search?q=r12+in+the+ARM+Procedure+Call+Standard) can find this question. – artless noise Aug 02 '23 at 19:46
2 Answers
Note that the ARM has STM and LDM instructions which store and load value in a numerically increasing/decreasing order. The registers R0-R3 are used as parameters and return values and are 'caller-saved' if needed. The registers R4-R8 are callee-saved registers (and maybe more). As well, R13-R15 are special registers. The use of R12 allows groups of registers to be accessed fairly efficiently with LDM/STM as you may want to treat groups differently (context save, function call, signal, etc. all have different requirements).
Function epilogue and prologue code may need to run calculations and/or save values. A scratch register is needed for this. So, given LDM/STM and other ARM addressing modes, the scratch register should NOT break continuous sequences. You may need to save/restore both caller and callee saved registers depending on context and code generation strategies. Having a break at R4 is not a good option. A natural break with least impact is between callee and upper intrinsic registers (PC,SP,LR). Note that R9-R11 can be special registers depending on the system (static base, stack extents, and frame pointer) in the prior APCS. As these are optional, in some systems they maybe saved as per R4-R8.
Why is r12 designated as scratch register according to the ARM Procedure Call Standard?
WHY is a very tough question. Given that it would complicate things not to use consecutive registers for similar functionality. It is also much easier to remember and does give more flexibility with some ARM instructions. Also the implementation of code generation is possibly simpler as you only need to save an upper limit to know callee-saved registers. A goal was to make function epilogue/prologue as fast as possible. This differs depending on function and system requirements. Hopefully why a scratch register is needed is obvious. Variable sized arrays based on parameters would be difficult to implement without multiple stack reservations. Some code such as signals may rely on FP to be atomically set during a prologue; Ie, you are in the function with stack and frame pointer set or you are not with no in-between. An IP (r12) is also useful for veneers and other linkage tricks (PLT,GOT,etc). The choice of R12 allows some systems to use R9-R11 as callee-saved general purpose registers without disrupting any sequence of similar registers.
From the APCS,
The ip register has a dedicated role only during function call; at other times it may be used as a scratch register.
(Aside: Conventionally, ip is used by compiler code generators as the/a local code generator temporary register).
Unfortunately, the APCS is obsoleted by the AAPCS so ARM does not provide it anymore (web references are hard to find). However, it gives in-sight into the evolution of the ARM ABI.
- 1
- 1
- 21,212
- 6
- 68
- 105
-
Probably the most important point here is that 'IP' is more for a compiler than an assembler programmer so it probably won't make sense (Ie, Why have it?) unless you look at compilers which your assembly may need to work with. Few people will be implementing linkers, loaders nor shared library systems where the IP might be important to an 'assembly coder'. Usually you don't want stack frames in assembly. – artless noise Jul 28 '17 at 16:11
-
Another important point not emphasized is that sometimes you need to save r0-r3 during asynchronous events. You may or may not need to save r4-r11 depending on the event. As well the storage (callee/caller) may end up being in different places; perhaps the system stack versus the user stack, or some thread/process/task control block. Having `ip` allows a register to get a pointer to this storage for either case. Which would at least make `r4` special as per the OPs idea. – artless noise Jul 14 '19 at 17:04
-
As I look back at this answer, another important aspect is the difference between R12 and R0-R3. Parameters are passed in R0-R3 so on entry they are not available to be used (depending on the function parameters). **R12 can always be used**. R0-R3 become 'scratch registers' as the routine proceeds. The R12 can be used by even the initial instruction. This is what makes it useful for veneers, etc. So R12 is **different** than R0-R3. Grouping it with these might make it seem the same; but it is conceptually different. A possible advantage but probably not the design intent. – artless noise Feb 01 '21 at 14:24
Page 14, 15, and 18 of the AAPCS Guide http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf defines the use of R12 the Intra- Procedure-call scratch register (IP). It is used by the linker to access the 32-bit address space that the Branch and Link (BL) instruction can not access.
- 252
- 2
- 6
-
1they could have used r4 or any other register. doesnt answer the question. – old_timer Jul 27 '17 at 23:28
-
@old_timer Page 15 says r12-r15 have special roles. In other words, r12 is grouped with r13-r15. – Andrey Portnoy Jul 28 '17 at 00:11
-
yep, doesnt answer the "why" question. SP, LR and PC are special registers yes, but r12 being the IP is arbitrary, it is not a special register in the instruction set just one that someone happen to chose, which you can or rather cant read about in the architectural reference manual, since it is not called out as a special register. so this doesnt answer the "why" question. 99.99999999% of the "why" questions have no real answer and have no real value on this site. – old_timer Jul 28 '17 at 03:46
-
"thirteen general-purpose 32-bit registers, R0 to R12", "three 32-bit registers with special uses, SP, LR, and PC, that can be described as R13 to R15" – old_timer Jul 28 '17 at 03:47
-
When you think about thumb mode r12 is a bad choice, it takes extra work to use vs say r4. A register you could have used universally rather than have extra work in thumb mode or define two different IP registers. – old_timer Jul 28 '17 at 03:50
-
1@old_timer *"99.99999999% of the "why" questions have no real answer and have no real value on this site."* not true – Andrey Portnoy Jul 28 '17 at 06:16
-
2@AndreyPortnoy Why questions are extremely difficult to answer as you need to know the intent and sometime this is not expressed. I agree about **no real value** being false. "Why" can lead to fundamental understanding that people with critical thinking need to handle a problem. – artless noise Feb 01 '21 at 14:30