This is the fifth day of my participation in Gwen Challenge
IOS basic principles + reverse article summary
This article mainly explains compiler optimization and pointer assembly
Compiler optimization
Set up the
Available in the projectBuildSetting->Optimization Level
Found in the general optimization scheme selectionFS
(Fastest, Smallest)
Case analysis
There is the following code
int main(int argc, char * argv[]) {
int a = 1;
int b = 2;
}
Copy the code
- The assembly without optimization is as follows
- Will optimize the program from
None
toFS
, compiled as follows
Modification 1: called in main
int sum(int a, int b){
return a + b;
}
int main(int argc, char * argv[]) {
sum(1, 2);
}
Copy the code
Check whether there is 1,2 at this time, and find that there is no assembly code related to sum. The optimization principle is as follows: removing sum has no impact on the result of program operationPrinciple 1: Code that has no effect on the result will be optimized by the compiler.
Modification 2: Print the result of sum
int sum(int a, int b){
return a + b;
}
int main(int argc, char * argv[]) {
int a = sum(1, 2);
printf(@"%d", a);
}
Copy the code
At this point, if sum is optimized, the execution result will be affected. You can see that the sum function has been optimized away,Optimization becomes a result
Pointer to the
In OC, either arguments or return values, if objects are passed/returned, these objects are Pointers. Let’s look at disassembly of Pointers
void func(){ int *a; printf("%lu", sizeof(a)); } int main(int argc, char * argv[]) {func(); }Copy the code
Analyze the assembly code of the above code
Pointer to the common sense
Pointer increment and decrement operations
void func(){ int *a; a = (int *)100; a++; printf("%d", a); } <! -- Print result --> 104Copy the code
-
Question: After a++, what is a?
- It’s 104 because
The incrementation and decrement of a pointer depend on the width of the data type to which it points
That is, because a points to the dataint
The width of int is 4 bytes
- It’s 104 because
-
Change 1: What is the result if int is changed to char?
- Because a points to the data
char
Char is 1 byte wide
- Because a points to the data
void func(){ char *a; a = (char *)100; a++; printf("%d", a); } <! -- Print results --> 101Copy the code
- Modification 2: What if int is changed to int*?
- Because a points to the data
int*
Is a pointer, and the width of the pointer is 8 bytes
- Because a points to the data
void func(){ int **a; a = (int **)100; a++; Printf ("%d", a); printf("%d", a); } <! Print the result --> 108Copy the code
- Change 3: What if I changed a++ to a = a+ 1?
Increment and decrement is related to the compiler!
- Note: the +1 is adding a step, while the step of a is (int*), which is 8 bytes
void func(){ int **a; a = (int **)100; // a++; A = a + 1; a = a + 1; printf("%d", a); } <! Print the result --> 108Copy the code
Pointers and Pointers evaluate
What is the result of subtracting two Pointers?
void func(){ int *a; a = (int *)100; int *b; b = (int *)200; int x = a - b; printf("%d", x); } <! -- Print the result --> -25Copy the code
-
Because the width of (100-200) /int = -100/4 = -25
-
Note: The unit of operation for Pointers is the width of the data type executed
-
Question: Can Pointers be if-else size ratios?
- Yes, we know that types can be converted to each other, but constructs and primitive types cannot be converted to each other
- Any type can be used
& (take address symbol)
The values
void func(){ int *a; a = (int *)100; int *b; b = (int *)200; if (a > b) { printf("a > b"); }else{ printf("a <= b"); }} <! -- Print result --> a <= bCopy the code
Disassembly of Pointers
Define a pointer, assign a value, and view its assembly code
void func(){
int *a;
int b = 10;
a = &b;
}
Copy the code
Below is a compilation and analysis of the code run
Pointer to an array
Question 1: Can I get an array out of an array correctly by using the following method?
void func(){ int arr[5] = {1, 2, 3, 4, 5}; for (int i = 0; i < 5 ; i++) { // printf("%d", arr[i]); printf("%d",*(arr + i)); // we can't use arr++ because the compiler doesn't allow}}Copy the code
It is possible to run discovery, so there are the following equivalents:
- Reciprocal relationship:
int *a == arr[0] == arr
Question 2: Is a++ ok in the for loop if arr is assigned to pointer A?
void func(){ int arr[5] = {1, 2, 3, 4, 5}; int *a = arr; for (int i = 0; i < 5 ; i++) { // printf("%d", arr[i]); printf("%d",*(a++)); }}Copy the code
It is also possible to run discovery
Basic usage of Pointers
- Define a pointer and take the value from the pointer
void func(){ char *p1; char c = *p1; // select * from p1;Copy the code
The cause is 0 as the address value. The following is the assembly analysis
* What if I rewrite it as p1 plus 0?
void func(){ char *p1; char c = *p1; Char d = *(p1+0); }Copy the code
View assembly code:
p1
Pointer toSp +0x8 value in the stack area
, which is equivalent toP1 - > 0 x0 (by 8)
c
That’s the same thing as taking the value of X8, which is equal to[X8]
d
Again, I’m going to take the value of X8, which is equal to[X8]
* What if I change it to p1 plus 1?
void func(){ char *p1; char c = *p1; Char d = *(p1+1); }Copy the code
View the assembly:
p1
Pointer toSp +0x8 value in the stack area
, which is equivalent toP1 - > 0 x0 (by 8)
c
That’s the same thing as taking the value of X8, which is equal to[X8]
d
Again, I’m going to take the value of X8, which is equal to[X8+0x1]
What if I changed a char to an int?
void func(){ int *p1; int c = *p1; Int d = *(p1+1); }Copy the code
The following is a compilation of func functions, where d is taken[x8+0x4]
The value of the address, because int is 4 bytes,0x4
isInt Step size
What if I changed an int to an int? *
void func(){ int **p1; int *c = *p1; Int *d = *(p1+1); }Copy the code
- View the assembly at this time
d
Is to take[x8+0x8]
The value of the address, because int* is a pointer, eight bytes long,0x8
isStep size of type int*
- How many bytes does int** need to be stretched?
The actual need is 3×8=24 bytes, since assembly is 16-byte alignment, sub minus 0x20 is required
- I’m going to add one more
int* p2
How many bytes does stack space stretch?
The discovery is still 0x20
- Let’s add one more
char c1
?
We’re over 32, so we need to stretch 16 more bytes
Multilevel pointer
1. Secondary Pointers
There is the following code
void func(){
int **p1;
int c = **p1;
}
Copy the code
Run the crash to see its compilation
-
X8 takes the value of *p1 (the address of the first-level pointer)
-
W9 takes the value of **p1 (the address of the second-level pointer)
2. Multi-level pointer addition operation
void func(){ char **p1; // char c = p1+2; Char c = *(*(p1 +2) +2); // The outermost layer of the +2, is added 0x2 (execute data type is char)}Copy the code
-
At this point, the +2 in C is +0x10 (execution data type is char*)
-
At this point, the outermost +2 in D is plus 0x2.
What about the following form?
void func(){ char **p1; // char c = p1+2; Char c = *(*(p1 +2) +2); Char c2 = p1[1][2]; // equivalent to the above}Copy the code
-
P1 [1] where 1 represents 0x8 (type char*)
-
P1 [1][2] where 2 represents 0x2 (type char)
From the results of the assemblyp1[1][2]
with*(*(p1 + 2) + 2)
Are equivalent
conclusion
-
Compiler optimization:
-
1, set: BuildSetting->Optimization Level
-
2. Principle of optimization: code that has no effect on the result is optimized by the compiler
-
3. Compiler optimization, which is essentially the optimization process of LLVM, actually optimizes assembly code (can be understood as assembly instructions will be reduced)
-
-
Pointer:
-
1. The increment and decrement of a pointer depends on the width of the data type to which the pointer is pointing. The operation is based on the data type to which the pointer is pointing (i.e. the width of the pointer – step).
-
2. The unit of operation of a pointer is the width of the data type to which it points
-
3. Pointers can be sized by if-else ratio because types can be converted to each other
-