preface

In the last article we explored some of the principles and interrelationships between CPUS and registers. We know that the execution of any high-level language method, at the bottom, is calling a function method. But have you ever wondered how the bottom of the function is implemented? Function calls must involve the function call stack, what is the function call path?

The stack and heap

What is theThe stack?The stackIs a storage space in memory with special access methods. followLast in, first out(Last In Out Firt) LIFO The opening of the stack for iOS is going from high address to low address.A local variable,parameterAnd so the dead stuff in the code is put in the stack space.

  • SP and FP registers

Sp register: saves our top stack address at any time. The FP register: also known as the X29 register is a general purpose register, but at some point we use it to save the address at the bottom of the stack! Sp saves stack top (open), FP saves stack low. The development of the stack space is through the stack pull up sub.

sub    sp, sp, #0x40             ; 
// Stretch the 0x40 (64 bytes) space
stp    x29, x30, [sp, #0x30];// X29 \x30 register push protection
add    x29, sp, #0x30            ;
// x29 points to the bottom of the stack frame. ldp x29, x30, [sp, #0x30];// Restore the value of register x29/x30
add    sp, sp, #0x40             ; 
/ / stack balance
ret
Copy the code

From the above assembly code, you can see stack space operations, as well as stack balancing. So what is stack balancing? The stack is to go to the low address, by sub minus can open up the address, through the add instruction can add the stack address restore this process is called stack balance.

  • Memory instructions

STR and LDR are stack space instructions. The STP instruction writes two pieces of data at the same time. When writing data, data cannot be directly written to the SP register, and the stack space needs to be stretched first. Read/write data is read/write to the higher address. The STR (Store register) instruction reads the data from the register and stores it in memory. LDR (Load register) instruction: to read data from memory and save it in a register. The LDR and STR variants LDP and STP can also operate two registers.

sub    sp, sp, #0x20    ;
// Stretch the stack space by 32 bytes
stp    x0, x1, [sp, #0x10];// add 16 bytes to sp to store x0 and x1
ldp    x1, x0, [sp, #0x10];// Take sp offset by 16 bytes and put it in x1 and x0
Copy the code

The purpose of the above assembly code is to use 32 bytes of space as the stack space of this program, and then use the stack to exchange the values of X0 and x1. […]. Addressing, storing the values on the left to the addresses on the right. Sp register is a pointer to a marker, sp operation must be 16 bytes aligned, 8 bytes operation will crash. The stored value is swapped but the memory address does not change. Bl instruction: put the address of the next instruction into the LR (X30) register, and go to the label to execute the instruction. Ret instruction: by default, the value of the LR (X30) register is used, and the underlying instruction prompts the CPU here as the address of the next instruction. ARM64 platform characteristic instruction, it has done the hardware optimization processing. X30 register: The X30 register holds the return address of the function. When the RET instruction is executed, the address value stored in the X30 register is looked for. In the case of nested function calls, we need to talk about X30 push.

  • Function parameters and return values

Under ARM64, the parameters of the function are stored in the 8 registers x0 through x7(w0 through w7). If there are more than 8 parameters, the stack is pushed. The return value of the function is placed in the X0 register. For efficiency, it is recommended that oc methods have no more than 6 parameters and functions no more than 8. Define arrays and structures to improve efficiency. System assembly is converted by LLVM.