iOS ARM:为什么不从main()调用除法例程?
我正在学习Mach-O符号化过程是如何工作的,我编写了一个简单的C程序来测试一些假设。我有以下C代码:iOS ARM:为什么不从main()调用除法例程?,ios,c,assembly,arm,Ios,C,Assembly,Arm,我正在学习Mach-O符号化过程是如何工作的,我编写了一个简单的C程序来测试一些假设。我有以下C代码: #include <stdio.h> #include <stdlib.h> int division(int a, int b); int m; int main(void) { int i,j; printf("initializing i\n"); i = 10; printf("initializing j\n");
#include <stdio.h>
#include <stdlib.h>
int division(int a, int b);
int m;
int main(void)
{
int i,j;
printf("initializing i\n");
i = 10;
printf("initializing j\n");
j=1;
printf("i = %d, j = %d\n", i, j);
m = division(i, j);
printf("m = %d / %d = %d\n", i, j, m);
return 0;
}
int division(int a, int b)
{
return a / b;
}
虽然我知道clang中的优化将除法函数替换为对libsystem.dylib中divsi3例程的调用,但我没有看到从主例程到__divsi3例程存根的任何调用,如BLX __除法或类似的调用。我猜现在不是这样,而是利用了m指针。它是如何工作的?有什么想法吗?编译器首先内联'division'函数,这意味着'a/b'变成'i/j'。然后它意识到“i/j”是一个常量表达式,它的计算结果总是“10/1”,在编译时它的计算结果仅为“10”(或十六进制中的0xA) 此行将“10”加载到R4中,以便以后可以将其写入“m”:
__text:0000BF2A MOVS R4, #0xA
此行将“10”加载到R3中,以便将“m”作为第四个printf参数传递:
__text:0000BF3A MOVS R3, #0xA
有时编译器非常聪明(比如内联和编译时常量表达式求值),有时则非常愚蠢(比如冗余地将“10”加载到R4和R3中,而不是将R3存储到“m”中)
p.S._m_ptr只是一个用来存储'm'地址的内存位置。编译器首先内联'division'函数,这意味着'a/b'变成'i/j'。然后它意识到“i/j”是一个常量表达式,它的计算结果总是“10/1”,在编译时它的计算结果仅为“10”(或十六进制中的0xA) 此行将“10”加载到R4中,以便以后可以将其写入“m”:
__text:0000BF2A MOVS R4, #0xA
此行将“10”加载到R3中,以便将“m”作为第四个printf参数传递:
__text:0000BF3A MOVS R3, #0xA
有时编译器非常聪明(比如内联和编译时常量表达式求值),有时则非常愚蠢(比如冗余地将“10”加载到R4和R3中,而不是将R3存储到“m”中)
p.S._m_ptr只是一个用来存储“m”地址的内存位置。有趣的观察。谢谢回答得好!我想说,编译器在处理简单的测试代码时非常聪明,但在实际问题上却愚蠢得令人难以置信。有趣的观察。谢谢回答得好!我想说,编译器在处理简单的测试代码时非常聪明,但在真正重要的时候却愚蠢得令人难以置信。