|
The origin of scratch is from the ABI; the majority of this answer is that no, the CPU itself does not have scratch register. Registers are symmetric in RISC design. It is a convention used by an ABI to simplify inter-operability between modules. An assembler programmer does not need to adhere to this, except for external interfaces. Ie, using assembler with C or other machine generated code. The ABI is intelligent and can be useful to follow, but it is not ingrained in the CPU itself. Why do we have a scratch register in ARM Architecture? It is efficient because scratch registers do not need to be saved before use. You need at least one scratch register to do many function prologue and epilogue activities. This is a 'use case'. How the processor uses it It is just a regular register to the processor. There is no 'scratch register' in the ARM CPUs [it is only fiat of the ABI or language inter-operability]. You might refer to it as a 'caller' saved register; but that is the EABI/AAPCS or whatever you might conform to. It is not inside the 'architecture'. It is a convention used for code to inter-operate. This can include OS calls, library calls and tool inter-operation (cross language calls). Different, but very similar, standards may be in effect depending on the software infra-structure/tools you are using. For traditional ARM, there are four 'caller' saved registers. They are r0-r3. They are also parameters to function and the return value. A routine that is made to inter-operate may use r0-r3 for any purposes even if they are not part of the parameter list. For instance a routine like, void foo(void) will not even need r0, but the routine may use r0 without saving it. The routine that calls foo() must save r0 if it is important to preserve. In this case, the r0-r3 are short lived registers or scratch registers. Contrast to registers r4-r11note which must be saved (on stack) if they are to be used. The r12 or ip which is generally not special to assembler and can also be treated as a scratch register. r12 is a scratch, but for different reasons than r0-r3. r12 is not used as a parameter register, so it can be used by prologue code (start of routine). There maybe additional restriction if you want your routine to be used in a 'back trace'. You can mark your routine as 'untraceable' for stack back traces with the pseudo-op .cantunwind. This is not ARM assembler but will be 'meta-data' in an ELF file. In this case, you can use r14 (lr) as a saved register; not a scratch. In a pure assembly project, all register can be scratch registers. For example the initial code that boots a processor doesn't usually need to save anything and all registers are scratch. An exception might be the stack pointer. Note: Some systems will special purpose r9, but it is rare. One example might be u-boot. r9 is never a scratch register. (责任编辑:) |
