Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS ARM:为什么不从main()调用除法例程?_Ios_C_Assembly_Arm - Fatal编程技术网

iOS ARM:为什么不从main()调用除法例程?

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");

我正在学习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");
    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”地址的内存位置。

有趣的观察。谢谢回答得好!我想说,编译器在处理简单的测试代码时非常聪明,但在实际问题上却愚蠢得令人难以置信。有趣的观察。谢谢回答得好!我想说,编译器在处理简单的测试代码时非常聪明,但在真正重要的时候却愚蠢得令人难以置信。