次のコードは、linux-x86、darwin-x86 では正常に動作しますが、ios-armv7 では動作しません。
正しい出力は次のようになります。
m[0]: 0.500000、v: 0.500000
m[1]: 0.500000、v: 0.500000
m[2]: 0.500000、v: 0.500000
m[3]: 0.500000、v: 0.500000
m[4]: 0.500000、v: 0.500000
しかし、間違った出力が見つかりました:
m[0]: 0.500000、v: 0.500000
m[1]: 0.500000、v: 0.000000
m[2]: 0.500000、v: 0.000000
m[3]: 0.500000、v: 0.000000
m[4]: 0.500000、v: 0.000000
また、ios-armv7 用にビルドされたときの状況もわかりました。
[a] 関数「func」を削除し、関数本体を「main」関数に移動すると、正常に動作します
[b] 配列 'm[5]' を 'double m[5]' として宣言すると、正常に動作します
[c] 変数 'v' を 'v = 0.5 または v = sqrt(2.0f/8)' に設定すると、問題なく動作します
[d] gcc 最適化オプションが「-O0」の場合は正常に動作しますが、「-O1 または -O2」の場合は間違った出力が発生します。
私の iPad1 はクラックされたので、MacBook Air で実行可能ファイルをクロスコンパイルし、その実行可能ファイルを iPad1 に「scp」して実行できます。詳細は次のとおりです。
1. Mac で実行可能ファイルをクロスコンパイルします。
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc -O1 -Wall -arch armv7 -mcpu=cortex-a8 -isysroot /Applications/Xcode.app/Contents/ Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/usr/include - D__IPHONE_OS__ -miphoneos-version-min=4.0 foo.c
2.実行可能ファイルをiPadに「scp」します
scp a.out mobile@192.168.1.106:~
3.iPadに「ssh」
ssh mobile@192.168.1.106 #デフォルトのパスワードは「alpine」
4. iPad で a.out を実行する
./a.out
#include <stdio.h>
#include <math.h>
int
func(int n) /* [a] */
{
int i;
float m[5]; /* [b] */
double v;
v = sqrt(2.0f/n); /* [c] */
for(i=0;i<5;++i) {
m[i]=v;
printf("m[%d]: %f, v: %f\n", i, m[i], v);
}
return 0;
}
int
main(int argc, char **argv)
{
return func(8);
}
https://gist.github.com/ashun/5992120でもコード全体を見つけることができます
以下が組み立てです。コマンド「vim -d」の助けを借りて違いを見つけることができます
- 前のコードのアセンブリでは、配列 'm[5]' を 'double m[5]' として宣言します。
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.section __TEXT,__const_coal,coalesced
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16
.section __TEXT,__StaticInit,regular,pure_instructions
.syntax 統一
.section __TEXT,__text,regular,pure_instructions
.globl _func
.align 2
.コード 16
.thumb_func _func
_関数:
push {r4, r5, r6, r7, lr}
r7、sp、#12 を追加
str r8, [sp, #-4]!
サブ sp #8
vmov.f32 s0、#2.000000e+00
movw r8, :lower16:(L_.str-(LPC0_0+4))
vmov s2、r0
movt r8, :upper16:(L_.str-(LPC0_0+4))
vcvt.f32.s32 d1、d1
LPC0_0:
r8、pcを追加
movs r4、#0
vdiv.f32 s0、s0、s2
vsqrt.f32 s0、s0
vcvt.f64.f32 d16、s0
vmov r5、r6、d16
LBB0_1:
移動r1、r4
移動r0、r8
移動r2、r5
移動r3、r6
vstr.64 d16、[sp]
r4、#1 を追加
blx_printf
cmp r4、#5
bne LBB0_1
移動 r0、#0
spを追加、#8
ldr r8、[sp]、#4
ポップ{r4、r5、r6、r7、pc}
.globl _main
.align 2
.コード 16
.thumb_func _main
_主要:
{r7, lr} を押す
mov r7、sp
movs r0、#8
bl_func
移動 r0、#0
ポップ{r7、pc}
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "m[%d]: %f, v: %f\n"
.subsections_via_symbols
- 前のコードのアセンブリでは、配列 'm[5]' を 'double m[5]' として宣言します。
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.section __TEXT,__const_coal,coalesced
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16
.section __TEXT,__StaticInit,regular,pure_instructions
.syntax 統一
.section __TEXT,__text,regular,pure_instructions
.globl _func
.align 2
.コード 16
.thumb_func _func
_関数:
push {r4, r5, r6, r7, lr}
r7、sp、#12 を追加
str r8, [sp, #-4]!
**vpush {d8}**
サブ sp #8
vmov.f32 s0、#2.000000e+00
movw r8, :lower16:(L_.str-(LPC0_0+4))
vmov s2、r0
movt r8, :upper16:(L_.str-(LPC0_0+4))
vcvt.f32.s32 d1、d1
LPC0_0:
r8、pcを追加
movs r4、#0
vdiv.f32 s0、s0、s2
vcvt.f64.f32 d16、s0
vsqrt.f64 d8、d16
vmov r5、r6、d8
LBB0_1:
移動r1、r4
移動r0、r8
移動r2、r5
移動r3、r6
vstr.64 d8、[sp]
r4、#1 を追加
blx_printf
cmp r4、#5
bne LBB0_1
移動 r0、#0
spを追加、#8
vpop {d8}
ldr r8、[sp]、#4
ポップ{r4、r5、r6、r7、pc}
.globl _main
.align 2
.コード 16
.thumb_func _main
_主要:
{r7, lr} を押す
mov r7、sp
movs r0、#8
bl_func
移動 r0、#0
ポップ{r7、pc}
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "m[%d]: %f, v: %f\n"
.subsections_via_symbols