- Cã«ãã£ãŠçæãããã³ãŒãã¯ã©ã®ããã«èŠããŸããïŒ ïŒARMã®äœçœ®ããïŒ
- Javaã«ãã£ãŠçæãããã³ãŒãã¯ã©ã®ããã«èŠããŸããïŒ
- ã³ãŒãã¯ã©ã®ããã«ãã©ãã§å®è¡ãããŸããïŒ
ãããã£ãŠããã®èšäºã¯3ã€ã®ããŒãã«åãããŠããŸãã
ç§ã¯ãã®ãããªè³ªåãæããããŠããããç 究ããããã«æããŸã-ã¢ã³ããã€ãã¯ãã§ã«ãããšãèžãã§ããŠããããç¥ããã«ãã®ãæ°ã«å ¥ãã®ããŒã«ã®1ã€ïŒããšãã°CïŒãæ£ãããªãã®ã§ãã³ãŒãã®ãã®åŸã®å·çã®éèŠãªãã€ã³ãã§ãã
ãã以åã¯ãä»®æ³ãã·ã³ãå®éã«ã¯åæããŠããŸããã§ããããä»ã¯Dalvik VMã«èå³ããããŸãã ãããã£ãŠã説æå šäœããã®VMã«é©çšããããã¬ãŒã·ã§ã³ã芳å¯ã§ããŸãããã¬ãŒã·ã§ã³ã®ã³ãŒã¹ã¯æ°åå€æŽãããŸãã
ãšã³ããªãŒ
ãã®èšäºãç解ããã«ã¯ãARMã¢ãŒããã¯ãã£ã®ã¢ã»ã³ãã©ãŒã®åºæ¬çãªç¥èãå¿ èŠã§ãã ãããç解ããããã®èšäºã«ã¯ã»ãšãã©æ å ±ããããŸããããèªè ããããç¥ããªããšããäºå®ã«éç¹ã眮ãããŠããŸãã ãããã£ãŠããããªãèªèº«ã®èšèã§ãå€ãã®èª¬æããããŸããããã以äžã¯ãããŸããã
ãŸããAndroidã¢ããªã±ãŒã·ã§ã³ãæåããäœæããã¹ãã«ãæã£ãŠããå¿ èŠããããŸãïŒãã£ã¬ã¯ããªæ§é ãšã¡ã€ã³ãã¡ã€ã«ãç¥ã£ãŠããïŒã
åèšäºã®çµæãèŠãŠãèªãã¹ããã©ããã確èªããããšãã§ããŸãã
3ã€ã®éšåã¯ãã¹ãŠè·éã倧ããç°ãªãã匷床ãã»ãŒåãã§ãã ããšãã°ã3çªç®ã®éšåã«ç§»åãããšãæåã®éšåã«é¢é£ããŠ2çªç®ã®éšåãš2çªç®ã®éšåã®ããã«è€éãªããã«èŠããŸãã ãã®ãããã¢ã€ãã ãææããŠããªãå Žåã¯æ³šæããŠãã ãããæçµçã«ã¯è² è·ã倧ãããªãå¯èœæ§ããããŸãã
誰ãèšäºã«èå³ãæã¡ãŸãã
åéºè ã ãã
åªããéçºè ã¯ã圌ããããç¥ããªãå Žåãç°¡åã«èŠã€ããŸãïŒåªããéçºè ã«å¯Ÿããç§ã®ç解ãããã»ã©é«ããªãããšãæã¿ãŸãïŒããäœããå§ããŠè©ŠããŠã¿ããããæ¹æ³ãç¥ããªã人ã¯ã圌ã«ãšã£ãŠéåžžã«é£ããã§ãããã
Dalvik VMã®ãããªé¬±denseãšãã森ã®äžã§ãèªåèªèº«ã«è³ªåããŠçããèŠã€ããããšã¯çŸå®çã§ãããåã倧èãªè¡åããšãããšã決ãã人ã«ãã®æ¹æ³ã瀺ããããšæããŸããã
æåã®ç®æš
ç§ã®äž»ãªã¿ã¹ã¯ã¯ãCã³ãŒããæ¯èŒããããšã§ãã
int sum(int a, int b) { return a + b; }
åãJavaã³ãŒãã®å ŽåïŒ
public class Summator { int sum(int a, int b) { return a + b; } static int staticSum(int a, int b) { return a + b; } }
public class NativeSummator { native int sum(int a, int b); static native int staticSum(int a, int b); }
ããã€ãã®ä»®å®ããããŸãããç§ã¯æ¬åœã«ãããå®éã«ã©ã®ããã«èµ·ããããèŠããã§ãã
äºåç¥è
ããã§ãJNIãä»ããŠãJavaã§ã®Cã³ãŒãã®çµ±åãã©ã®ããã«èŠããããæãåºããŸãã
Javaã³ãŒãã§å€éšïŒãã€ãã£ãïŒé¢æ°ã䜿çšããã«ã¯ãnativeããŒã¯ãŒãã䜿çšãããŸãã
package com.m039.study; public class Summator { native int sum(int a, int b); }
ãã®å ŽåãCã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
int Java_com_m039_study_Summator_sum(JNIEnv* env, jobject thiz, int a, int b) { return a + b; }
Javaãé¢æ°ã衚瀺ããã«ã¯ãç¹å®ã®ã«ãŒã«ïŒã¡ã¢ãªããäžããããïŒã«åŸã£ãŠæ§æããå¿ èŠããããŸãã
- ååã¯javaã§å§ãŸããŸã
- 次ã®ãã¹ãå«ãŸããŸãïŒã¢ãžã¥ãŒã«+ã¯ã©ã¹å+é¢æ°å
- 2ã€ã®è¿œå ã®åŒæ°ãé¢æ°ã«æž¡ãããŸãïŒç°å¢ãžã®ãã€ã³ã¿ãŒãšãªããžã§ã¯ããŸãã¯ã¯ã©ã¹ãžã®æ§é ïŒã¡ãœãããéçãªå ŽåïŒ
ã³ã³ãã€ã«ã«ã¯ã
ndk-build
ã³ãã³ãã䜿çšãããŸãã ãã®ã³ãã³ãã¯ãCïŒãŸãã¯C ++ïŒãã¡ã€ã«ã./jniãã£ã¬ã¯ããªã«ããããšãæ³å®ããŠããŸãã ãã£ã¬ã¯ããªã«ã¯Android.mkãã¡ã€ã«ãå«ãŸããŠããå¿ èŠããããApplication.mkã§ããå ŽåããããŸãã
ã³ã³ãã€ã«åŸãlibNAME.soã©ã€ãã©ãªã¯./libs/armebiãã£ã¬ã¯ããªã«äœæãããŸãããarmebiã¯ç°ãªãå ŽåããããŸãã
ãã詳现ãªæé ãå¿ èŠãªå Žåã¯ãå¥ã®ããã¥ã¡ã³ããåç §ããå¿ èŠããããŸãã NDKã«æ·»ä»ãããŠããããã¥ã¡ã³ããšãµã³ãã«ã®ã«ã¿ãã°ãã芧ãã ãã ã
ããŒãI. Cã«ãã£ãŠçæãããã³ãŒãã¯ã©ã®ããã«èŠããŸããïŒ
質åïŒCã³ãŒãã¯æ£ç¢ºã«äœãããŸããïŒ
ååãšããŠãããã¯ç解ã§ããŸãããARMã¢ãŒããã¯ãã£ã®èŠ³ç¹ããèŠããšã ã»ãšãã©ãã¹ãŠã®ã¢ãã€ã«ããã€ã¹ããã®ç¹å®ã®ã¢ãŒããã¯ãã£ã䜿çšããŠããŸããïŒ
ãããç解ããã«ã¯ãCã³ãŒããã¢ã»ã³ãã©ãŒïŒçïŒåœ¢åŒã§ã©ã®ããã«èŠããããç解ããå¿ èŠããããŸãã
å解ãã
äž»ãªè³ªåã¯ãCãšJavaã®çžäºäœçšã§ããããã«åºã¥ããŠã5ã€ã®äŸãéžæããŸããã
1.æšæºïŒ
int sum(int a, int b) { return a + b; }
2. JNIãä»ãããã€ã³ãïŒéçã§ã¯ãªãïŒïŒ
int Java_com_m039_study_Summator_sum(JNIEnv* env, jobject thiz, int a, int b) { return a + b; }
3. JNIçµç±ã®ãã€ã³ãã£ã³ã°ïŒéçïŒïŒ
int Java_com_m039_study_StaticSummator_sum(JNIEnv* env, jclass thiz, int a, int b) { return a + b; }
4. JNIãä»ãããã€ã³ãïŒéçã§ã¯ãªããé¢æ°ã䜿çšïŒïŒ
int Java_com_m039_study_Summator_sum(JNIEnv* env, jobject thiz, int a, int b) { return sum(a, b); }
5. JNIãä»ãããã€ã³ãïŒéçãé¢æ°ã䜿çšïŒïŒ
int Java_com_m039_study_StaticSummator_sum(JNIEnv* env, jclass thiz, int a, int b) { return sum(a, b); }
å°ãèããŠã¿ãŸãããã 4ãš5ã¯ãå®å šã§ã¯ãªãã«ããŠããã»ãšãã©äŒŒãŠããããã«æããŸãã 1-3ã¯ãéä¿¡ããããã©ã¡ãŒã¿ãç°ãªãå¿ èŠããããŸãã ããã¯ç§ã確èªããããã®ã§ãã
ãã«ãã·ã¹ãã
Androidã¢ããªã±ãŒã·ã§ã³ã®ãã«ãã·ã¹ãã ã¯éåžžã«åçŽåãããŠãããAndroidã®ã³ã³ãã€ã«æžã¿ã³ãŒãããã§ãã¯ãããªã©ã®ç®çã§ãã³ã³ãã€ã«ãã©ã°ãç¥ãå¿ èŠããããŸãã ç¹ã«ãæé©åãã©ã°ã
Application.mkãã¡ã€ã«ã§ã¯ã
APP_OPTIM
å€æ°ãå€æŽããŠããªãªãŒã¹ãŸãã¯ãããã°ã®2ã€ã®å€ã®ããããã«å²ãåœãŠãããšãã§ããŸãã
ãªããªã ãã®èšäºã®ç®çã¯ã2ã€ã®èšèªã®çµ±åãæ¯èŒããããšã§ããã1ã€ã®èšèªãããç解ããããšã§ã¯ãããŸããããã®åŸãæšè«ãç°¡åã«ããããã«ãå€ 'debug'ã䜿çšããŸãã ããã«ãããç解ãæ·±ãŸãããšã©ãŒãçºçããå¯èœæ§ãäœããªããŸãïŒãã®èšäºãæžãæ©äŒãå¢ããŸãïŒãããšã«ãããããªãªãŒã¹ãã¢ãŒãã®ã³ãŒãã®éãã調ã¹ãå¿ èŠããããŸãã
ä»ãããå°ã詳现ã
APPLICATION-MK.htmlãã¡ã€ã«ã«ã¯ã
APP_OPTIM
ãã©ã°ã®
APP_OPTIM
説æãããŠããã ã¢ããªã±ãŒã·ã§ã³ã¿ã°ã®å±æ§ã
android:debuggable="true"
å€æŽã§ãã
APP_OPTIM
å€æ°
APP_OPTIM
'debug'ã«èšå®
APP_OPTIM
ããããšã瀺ãããŠããŸãã å±æ§ãfalseã«èšå®ãããŠããå Žåã
APP_OPTIM
'release'ã«å²ãåœãŠãããŸãã
ãããã£ãŠã
android:debuggable
å±æ§ãAndroidManifest.xmlã§ãtrueãã«
android:debuggable
ãŠãããšããã«æ³å®ãããŠããŸãã
ãŸããå€æ°
APP_OPTIM
ã䜿çšãããšãã«ã³ã³ãã€ã©ãŒã«æž¡ãããå€ãéãããšã¯ã§ããŸãããåããã¡ã€ã«ã§ä»¥äžã®ããã«è¡šç€ºãããŸã ã
ifeq ($(APP_OPTIM),debug) APP_CFLAGS := -O0 -g $(APP_CFLAGS) else APP_CFLAGS := -O2 -DNDEBUG -g $(APP_CFLAGS) endif
次ã«ã5ã€ã®ãªãã·ã§ã³ãã¹ãŠãæ€èšãå§ããŸãã
ããããã°ãã¢ãŒã
泚 ïŒãã¹ãŠã®ãªã¹ãã¯ãã³ãã³ã
arm-linux-androideabi-objdump -d " "
ååŸãããŸãã
arm-linux-androideabi-objdump -d " "
ãªãã·ã§ã³1
00000804 <sum>: 804: b082 sub sp, #8 806: 9001 str r0, [sp, #4] 808: 9100 str r1, [sp, #0] 80a: 9a01 ldr r2, [sp, #4] 80c: 9b00 ldr r3, [sp, #0] 80e: 18d3 adds r3, r2, r3 810: 1c18 adds r0, r3, #0 812: b002 add sp, #8 814: 4770 bx lr 816: 46c0 nop (mov r8, r8)
ãã®ãªã¹ãã«ã¯å€ãã®äœåãªãã®ããããŸãããããã¯ãã¹ãŠåŒã³åºãèŠçŽãããå ·äœçã«ã¯ARMåŒã³åºãèŠçŽã®ããã§ãã
ç§ã¯ãã®äŸã翻蚳ããŸãïŒ
-04ïŒ2ã€ã®ããŒã«ã«å€æ°çšã«ã¡ã¢ãªãäºçŽããŸãã
-06-08ïŒé¢æ°ã«æž¡ãããåŒæ°ãä¿åããŸãã
-0a-0cïŒåãåŒæ°ãä»ã®ã¬ãžã¹ã¿r2ããã³r3ã«ããããæž¡ãããŸãã
-0eïŒr3 = r2 + r3ãšåç
-10ïŒçµæãã¬ãžã¹ã¿r0ã«ä¿åããŸã
-12ïŒã¹ã¿ãã¯ãã€ã³ã¿ãŒãåæç¶æ ã«æ»ã
-14ïŒå ã®å Žæã«æ»ã
-16ïŒnopã³ãã³ãã䜿çšããŠãã¡ã€ã«å ã®é¢æ°ãæŽåãã
è¿œå ïŒ2ã€ã®ãã€ã³ãã¯æ確ã§ã¯ãããŸããã§ããïŒãµãã£ãã¯ã¹sãšã³ãã³ãbxã æåã¯ãå®è¡æã«ã¹ããŒã¿ã¹ãã©ã°ãæŽæ°ãããããšãæå³ããŸãã 2çªç®ã¯thumbã³ãã³ãã§ãblã³ãã³ããšåçã§ãã
ã³ãŒããåãã åŸãããã«å€ãã®ãã®ãããããšãæããã«ãªããŸããã ãã¡ãããæé©åã䜿çšããå Žåããã®ãããªãã®ã¯ãããŸããã§ããã
ãã®ãªã¹ãã«ã¯ãåŒæ°ãé¢æ°ã«ã©ã®ããã«æž¡ãããäž»èŠéšåãã©ã®ããã«å®è¡ããããã瀺ã2ã€ã®ãã€ã³ããããããŸããã
åŒæ°ã¯ã¬ãžã¹ã¿ãä»ããŠæž¡ãããã¡ã€ã³éšåã«ã¯ã³ãã³ãã1ã€ã ãå«ãŸããŸãã ãããããã³ãŒã
adds r0, r1, r2; bx lr
ããããšã確èªã§ããŸãã
adds r0, r1, r2; bx lr
adds r0, r1, r2; bx lr
ã¯ååšããæš©å©ããããŸãã
ãã ãããã®ãããªã³ãŒããå®æããã¢ããªã±ãŒã·ã§ã³ã«ãããšã¯èšããŸããïŒèª°ããããããã°ãããŒãžã§ã³ãåžå Žã«ãªãªãŒã¹ããããšã決å®ããªãéãïŒã ãããŠãJavaã§ã¯ãã¹ãŠãæªåããŠãããšããä»®å®ããããŸãããç§ã¯ããã確èªããããšæããŸãã ãããã£ãŠãæ®ãã®ãªã¹ãããã°ãã確èªããå¿ èŠããããŸãã
ãªãã·ã§ã³2
000007ec <Java_com_m039_study_Summator_sum>: 7ec: b084 sub sp, #16 7ee: 9003 str r0, [sp, #12] 7f0: 9102 str r1, [sp, #8] 7f2: 9201 str r2, [sp, #4] 7f4: 9300 str r3, [sp, #0] 7f6: 9a01 ldr r2, [sp, #4] 7f8: 9b00 ldr r3, [sp, #0] 7fa: 18d3 adds r3, r2, r3 7fc: 1c18 adds r0, r3, #0 7fe: b004 add sp, #16 800: 4770 bx lr 802: 46c0 nop (mov r8, r8)
ã¯ããã¯ããåãããšããããŠäºæ³ã©ãããåŒæ°ã®æ°ã ããå¢ããŸããã ãããŠãäœåã®äžå¿ èŠãªæäœãææã ãããåæã«ãæé©åãããããŒãžã§ã³ãèŠãããšãã欲æ±ã¯ã¯ããã«å€§ãããªããŸãã
泚 ïŒå€ãã®JNIé¢æ°ïŒè¿œå ã®åŒæ°ãæž¡ãããïŒã䜿çšããããšã¯ãåçŽãªé¢æ°ïŒããå°ãªãåŒæ°ãæž¡ãããïŒãããæªããšããä»®å®ã確èªãããŠããŸãã ïŒä»ããã®èšäºãæžãçŽããŠãããšãããã®å£°æã¯éåžžã«çŽ æŽã«èãããŸãïŒ
ãªãã·ã§ã³3
00000850 <Java_com_m039_study_StaticSummator_sum>: 850: b084 sub sp, #16 852: 9003 str r0, [sp, #12] 854: 9102 str r1, [sp, #8] 856: 9201 str r2, [sp, #4] 858: 9300 str r3, [sp, #0] 85a: 9a01 ldr r2, [sp, #4] 85c: 9b00 ldr r3, [sp, #0] 85e: 18d3 adds r3, r2, r3 860: 1c18 adds r0, r3, #0 862: b004 add sp, #16 864: 4770 bx lr 866: 46c0 nop (mov r8, r8)
ä»®å®ã¯æ£åœåãããã³ãŒãã¯ãªãã·ã§ã³2ãšåãã§ãã
ãªãã·ã§ã³4
000008e0 <Java_com_m039_study_Summator_sum>: 8e0: b500 push {lr} 8e2: b085 sub sp, #20 8e4: 9003 str r0, [sp, #12] 8e6: 9102 str r1, [sp, #8] 8e8: 9201 str r2, [sp, #4] 8ea: 9300 str r3, [sp, #0] 8ec: 9a01 ldr r2, [sp, #4] 8ee: 9b00 ldr r3, [sp, #0] 8f0: 1c10 adds r0, r2, #0 8f2: 1c19 adds r1, r3, #0 8f4: f7ff ffde bl 8b4 <sum> 8f8: 1c03 adds r3, r0, #0 8fa: 1c18 adds r0, r3, #0 8fc: b005 add sp, #20 8fe: bd00 pop {pc}
ãªããã®ãªãã·ã§ã³ãæ€èšããå¿ èŠãããã®ã§ããïŒ JNIé¢æ°ã§ãã¹ãŠãæžãæ¹ãè¯ããšæã£ãå Žåã«åããŠã äžæ¹ãå®éã«ã¯ãJNIãããè€éãªèšèšã®ã©ãããŒãšããŠäœ¿çšããããšããå§ãããŸãã ãŸããå°ããªCé¢æ°ã§ã¯ãäœã§ãã§ããŸãã ïŒ æ³š ïŒãã®èšäºãæžããåŸããã®å£°æã¯ãã§ã«ç§ã«ã¯æãããªããã§ãïŒ
ãã®ã³ãŒãã¯ããå°ãè€éã§ãïŒ
-e0ïŒè¿ä¿¡å ã¢ãã¬ã¹ãä¿åããŸã
-e2ïŒããŒã«ã«å€æ°çšã«ã¡ã¢ãªãäºçŽããŸã
-e4-eaïŒåŒæ°ãããŒã«ã«å€æ°ã«ä¿åããŸã
-ec-eeïŒããŒã«ã«å€æ°ã®å€ãååŸããŸã
-f0-f2ïŒé¢æ°åŒã³åºãã®ããã«ã¬ãžã¹ã¿ã®å€ãæºåããŸã
-f4ïŒé¢æ°åŒã³åºãèªäœ
-f8-faïŒçµæãã¬ãžã¹ã¿ã«ä¿åããæ»ãå€ã®ã¬ãžã¹ã¿ã«æžã蟌ã¿ãŸã
-fcïŒã¹ã¿ãã¯ãã€ã³ã¿ãŒãåæäœçœ®ã«æ»ããŸã
-feïŒåŒã³åºããå Žæã«ç§»åããŸã
ã¬ãžã¹ã¿lrãblåœä»€ãä»ããŠæžãæããããããšãèãããšãæååãe0ãã¯æ»ãã¢ãã¬ã¹ãæ ŒçŽããããã«äœ¿çšãããŸãã
ã芧ã®ãšãããäœåãªã³ãŒãããããããããŸãã ãã®ãããªã³ãŒãã«ã¯ååšããæš©å©ããããšæããŸãïŒ
push {lr} sub sp, #20 adds r0, r2, #0 adds r1, r3, #0 bl 8b4 <sum> add sp, #20 pop {pc}
ãªãã·ã§ã³5
æ€èšãã䟡å€ã¯ãªããšæããŸãã
ãªãªãŒã¹ã¢ãŒãã§
æé©åãããããŒãžã§ã³ã«å«ãŸããã³ãŒãã«ã€ããŠã®æšæž¬ããã¹ãããããšæããŸãã
ãªãã·ã§ã³1
0000894 <sum>: 894: 1808 adds r0, r1, r0 896: 4770 bx lr
ãªãã·ã§ã³2
00000890 <Java_com_m039_study_Summator_sum>: 890: 1898 adds r0, r3, r2 892: 4770 bx lr
ãªãã·ã§ã³3
00000898 <Java_com_m039_study_StaticSummator_SUM>: 898: 1898 adds r0, r3, r2 89a: 4770 bx lr
ãªãã·ã§ã³4
0000089c <Java_com_m039_study_Summator_SUM3>: 89c: b510 push {r4, lr} 89e: 1c10 adds r0, r2, #0 8a0: 1c19 adds r1, r3, #0 8a2: f7ff fff7 bl 894 <sum> 8a6: bd10 pop {r4, pc}
å°è±¡
ç§ã¯å°ãé©ããŠããŸãã ãã®åã«äžèŽããã¯ãã ã£ããã¹ãŠã®ãã®ã æé©åãããã³ãŒãã¯åªããŠãããç§ãèªåã§æžã蟌ãããšããã³ãŒãã«éåžžã«è¿ããã®ã§ãã
ããŒãI.ãŸãšã
ãã®ããŒãã§ã¯ãããããARMã§ã®ã¢ã»ã³ãã©ãŒã玹ä»ããŸãã ä»ã®èšèªæ§æèŠçŽ ãåæããŠç解ããããšãã§ããŸãã ãŸããããªãã®æšæž¬ã«é©ããããããŸããã
ããããæãéèŠãªããšã¯ãããªããã¢ã³ããã€ãéçºè ã§ããã°ãããã©ã«ãã®ã³ã³ãã€ã«èšå®ãã©ã®ããã«äœ¿çšãããå¿ èŠãªãšãã«ã©ããèŠãã¹ãããç解ã§ããããã«ãªããŸããã
æåã¯ãJavaã³ãŒããããCã³ãŒãã®æ¹ãã©ãã ãåªããŠããããç¥ããããšæããŸããã æåã¯èšäºãæžããŸãããããã®çµæãæžããŠããŸãã ä»ã®ãšãããCã®åé¡ã解決ããããšãããã«ãšã¬ã¬ã³ãã§ãå解ããã圢ã§ã©ãã ãã³ã³ãã¯ãã«ãªã£ããã«æ³šæãæãããšãã§ããŸãã Javaãªãã³ãŒãã§ã¯ããããèŠãããŸããããã§ã«å°ãªããªã£ãŠããŸãã ãããŠããªãã³ãŒããCãšæ··åšããŠãã3çªç®ã®èšäºã§ã¯ãããã¯å®éã«ã¯ãããŸããã
ãããŠä»ãJavaãªãã³ãŒãã«ã€ããŠå°ãã ã説æããŸãã
ããŒãII Javaã«ãã£ãŠçæãããã³ãŒãã¯ã©ã®ããã«èŠããŸããïŒ
æåã«ãJVMïŒãŸãã¯Dalvik VMïŒãã©ã®ããã«æ©èœããããç解ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãDalvik VMã®ãã€ãã³ãŒããã¡ã€ã«ã§ãã* .dexãã¡ã€ã«ãéã¢ã»ã³ãã«ããå¿ èŠããããŸãã
Summatorã¯ã©ã¹ã¯ã©ã®ããã«ãªããŸããïŒå ã®ç®æšãåç §ïŒïŒ ãããè¡ãã«ã¯ãããã°ã©ã
dexdump -d classes.dex
èšå®ããŸãã ã³ãã³ããçºè¡ãããã®ïŒ
#5 : (in Lcom/m039/study/Summator;) name : 'sum' type : '(II)I' access : 0x0000 () code - registers : 4 ins : 3 outs : 0 insns size : 3 16-bit code units 00226c: |[00226c] com.m039.study.Summator.sum:(II)I 00227c: 9000 0203 |0000: add-int v0, v2, v3 002280: 0f00 |0002: return v0 catches : (none) positions : 0x0000 line=73 locals : 0x0000 - 0x0003 reg=1 this com/m039/study/Summator; 0x0000 - 0x0003 reg=2 a I 0x0000 - 0x0003 reg=3 b I
name : 'staticSum' type : '(II)I' access : 0x0008 (STATIC) code - registers : 3 ins : 2 outs : 0 insns size : 3 16-bit code units 002100: |[002100] com.m039.study.Summator.staticSum:(II)I 002110: 9000 0102 |0000: add-int v0, v1, v2 002114: 0f00 |0002: return v0 catches : (none) positions : 0x0000 line=77 locals : 0x0000 - 0x0003 reg=1 a I 0x0000 - 0x0003 reg=2 b I
ããã§ã¯
add-int v0, v1, v2
ãããã³ãªãã³ãŒãã9000 0102ãã®å€ãèæ ®ããå¿ èŠããããŸãã ããã§ãå éšãããããã®ãªãã³ãŒããã©ã®ããã«èŠãããã«é²ãããšãã§ããŸãã
ç£èŠãããªãã³ãŒãã¯äœã§ããïŒ
ARMã¢ãŒããã¯ãã£ã«ãã£ãšèå³ããããŸãã ãã®ã¢ãŒããã¯ãã£ã¯ããã©ã«ãã§äœ¿çšãããããããªãã³ãŒããé©åã§ãã ããããå€ãã®ARMããããããã©ã«ãã§ã©ãã䜿çšãããŸããïŒ
ãããè¡ãã«ã¯ãApplication.mkããã¥ã¡ã³ããããå ·äœçã«ã¯å€æ°APP_ABIã®èª¬æãåç §ããŠãã ããã ããã©ã«ãã§ã¯armv5teã䜿çšããããšèšèŒãããŠããŸãã ããã§æ¢çŽ¢ããŸãïŒ
ã©ãããèŠèŽãå§ããŸããïŒ
ãªãã³ãŒãèªäœã¯armv5teãã£ã¬ã¯ããªã«ãããŸãã ãã®ãã£ã¬ã¯ããªã«ãããã¡ã€ã«ãæ€èšããã®ã¯æ£ããã§ãããããç§ã¯ããããŸã£ããæ£ãããªãæ¹æ³ã§ãããããšæã£ãŠããŸããããæ¢ã«çæããããã¡ã€ã«ãæ€èšããããã«ãæ©èœããŸãã ããå ·äœçã«ã¯ã InterpAsm-armv5te.SãFile ã ãšãŠãé¢çœããŠå®çšçã§ãã
ããã¥ã¡ã³ã
ãã¹ãŠã®äž»èŠãªããã¥ã¡ã³ãã¯docsãã£ã¬ã¯ããªã«ãããŸãããå¿ èŠã«å¿ããŠãçã®HTMLãããèªã¿ããã圢åŒãžã®ãªã³ã¯ãæäŸããŸãã
è¿œå ãªãã³ãŒãã®æ€æ»ïŒ0x90ïŒ
ãªãã³ãŒã0x90 ããã®ã³ãŒããèããŠã¿ãŸãããïŒ
.L_OP_ADD_INT: /* 0x90 */ /* File: armv5te/OP_ADD_INT.S */ /* File: armv5te/binop.S */ /* * Generic 32-bit binary operation. Provide an "instr" line that * specifies an instruction that performs "result = r0 op r1". * This could be an ARM instruction or a function call. (If the result * comes back in a register other than r0, you can override "result".) * * If "chkzero" is set to 1, we perform a divide-by-zero check on * vCC (r1). Useful for integer division and modulus. Note that we * *don't* check for (INT_MIN / -1) here, because the ARM math lib * handles it correctly. * * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, * mul-float, div-float, rem-float */ /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB .if 0 cmp r1, #0 @ is second operand zero? beq common_errDivideByZero .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST @ optional op; may set condition codes add r0, r0, r1 @ r0<- op, r0-r3 changed GET_INST_OPCODE(ip) @ extract opcode from rINST SET_VREG(r0, r9) @ vAA<- r0 GOTO_OPCODE(ip) @ jump to next instruction /* 11-14 instructions */
ã³ã¡ã³ããèŠããšããã¹ãŠãæ確ã«ãªããŸãããã³ãŒãå ã§ãããã®ã³ã¡ã³ããèªåã§èŠãããšæããŸãã ãããã£ãŠããã®ã³ãŒãã®äžéšãããã«åæããŸãã
ãªãã³ãŒã0x90ã¯å ç®åœä»€ã«å¯Ÿå¿ãããã®åœ¢åŒã¯23xã§ãã ããã¯ãåœä»€ãµã€ãºã2ãã€ãã§ããã3ã€ã®ã¬ãžã¹ã¿ã䜿çšããããšãæå³ããŸãããxãã¯ããã以å€ã«äœããªãããšãæå³ããŸãã
ãããã£ãŠããã®ãªãã³ãŒãã®ã³ãŒãã¯ããããã®3ã€ã®ã¬ãžã¹ã¿ãæœåºãã23x圢åŒã§éä¿¡ããå ç®ã«äœ¿çšããå¿ èŠããããŸãã ããããããã§ã¯ãã¹ãŠãããã»ã©åçŽã§ã¯ãªãããšãããããŸãã ã¬ãžã¹ã¿ã®æ¥é èŸãvããããšãã°ãvCCãã¯ãä»®æ³ãæå³ããŸãã ãããŠããªãã³ãŒããã¬ãžã¹ã¿çªå·ãæž¡ããåœä»€ãæå®ãããã¬ãžã¹ã¿ã«å«ãŸããå€ãååŸããããšãããããŸãã ïŒ æ³š ïŒã¬ãžã¹ã¿ãŒã«ã¯åžžã«æ¥é èŸãvããä»ããŠããããã§ã¯ãããŸããïŒ
次ã®ããã«ãªããŸãã
-ãªãã³ãŒãããããŸãïŒ00 | 90 02 | 01ïŒAA | op CC | BBïŒ*
-90ã¯ãªãã³ãŒããè¿œå ããããšãæå³ããŸã
-ã¬ãžã¹ã¿çªå·ãæœåºr9 = 0ãr2 = 1ãr3 = 2
-ã¬ãžã¹ã¿ã®å 容ãæœåºããŸãr1 = REGïŒr3ïŒãr0 = REGïŒr2ïŒ**
-ãadd r0ãr0ãr1ããšããåœä»€ãå®è¡ããŸã
-æ»ãå€REGïŒr9ïŒ= r0ãä¿åããŸã
*èªèã容æã«ããããã«ãããã¥ã¡ã³ããšåæ§ã«è¿œå |
** REG-æ¬äŒŒã³ãŒãã§ã
ãã®ãªãã³ãŒãã«ã¯ãå¥ã®ãªãã³ãŒãã«åãæ¿ããããã«å¿ èŠãªã³ãã³ããå«ãŸããŠããŸãã å°ãåæããã®ã§ãä»ã¯æ³šæãæã£ãŠã¯ãããŸããã
ãããŠä»ãããã¯ãã¹ãŠã¢ã»ã³ãã©ãŒãŸãã¯ããå³ãã説æã§ã©ã®ããã«èŠããŸããïŒ
1. FETCH ïŒr0ã1ïŒã ãã®ãªãã³ãŒãïŒ0x90ïŒã¯ãr4ãšr5ã«å¯Ÿå¿ãã2ã€ã®ã¬ãžã¹ã¿rPCãšrINSTïŒåäžïŒã䜿çšããŸãã å°ãäžãèŠããšãrINSTïŒ FETCH_INST ïŒãrPCã®å€ã§ããããšãããããŸãã ãããã£ãŠãrINSTã¯FETCHã³ãã³ãã®å€ïŒrINSTã0ïŒãšçãããšèšããŸãã
2.ã¬ãžã¹ã¿çªå·ã¯ãæšæºã®æ¹æ³ã䜿çšããŠååŸãããŸãã ïŒåçãåç §ïŒ
3. GET_VREG ïŒr1ãr3ïŒã æ°ããrFPã¬ãžã¹ã¿ã衚瀺ãããŸãã ãã®ã¬ãžã¹ã¿ã¯ãããŒã«ã«å€æ°ãšåŒæ°ã®ã¡ã¢ãªé åãæããŸãã ã€ãŸã ããã«ãããåŒæ°ã®å€ãæœåºããæ»ãå€ãæžã蟌ãããšãã§ããŸãã VMã®å éšã¬ãžã¹ã¿ãŒãžã®ãã€ã³ã¿ãŒãšããŠè¡šãããšãã§ããŸãã
4. .if 0 ... .endifã¯ãããã«ããã§ãããInterpAsm-armv5te.SïŒãã¡ã€ã«ã§èª¿æ»ãéå§ããããã§ãã binop.Sãã¡ã€ã«ãèŠããšããã®ãªãã³ãŒãã®2çªç®ã®åŒæ°ã§ãããŒãã®ãã§ãã¯ãç¡å¹ã«ãªã£ãŠããããšãæããã«ãªããŸãã
5. FETCH_ADVANCE_INSTïŒ2ïŒã®è©³çŽ°
6.è¿œå ãé²è¡äžã§ã
7. GET_INST_OPCODEïŒipïŒã«ã€ããŠããã«èª¬æããŸãã
8. SET_VREG ïŒr0ãr9ïŒã¯ãæ»ãå€ã察å¿ããã¬ãžã¹ã¿ã«æžã蟌ã¿ãŸãããã®ã¬ãžã¹ã¿ã®çªå·ã¯r0ã§æå®ãããŸãã
9.åŸã§èª¬æããGOTO_OPCODEïŒipïŒ
ç§ã¯èŠèŠçãªïŒç§ã¯é¡ã£ãŠããŸãïŒåçãæããŸããïŒ
ãªãã³ãŒãã¯åãã¢ã»ã³ãã©ã³ãŒãã«äŒŒãŠããïŒãr0ãr1ãr0ãè¿œå ãããïŒã ãã§ãä»®æ³ã¬ãžã¹ã¿ã®åŠçãšæ¬¡ã®ãªãã³ãŒããžã®ç§»åãšãã2ã€ã®è¿œå ã ãã§ãããšçµè«ä»ããããšãã§ããŸãã
審æ»åã®éšå
ä»®æ³ã¬ãžã¹ã¿ã®åŠçãèæ ®ãããŸããã ãªãã³ãŒãã®ä»ã®ããŒã ãäœãããŠããã®ããç解ããå¿ èŠããããŸãã圌ããããŸãã«ãé ããªãããšãé¡ã£ãŠããŸãã ããšãã°ãrFPãrPCãªã©ã®ã¬ãžã¹ã¿ã®å€ãåæåãããå Žåã èå³æ·±ãããšã§ã¯ãããŸãããç®æšããã®åŒ·ãåå²ã§ãã
次ã«ãæ®ãã®ã³ãã³ããæ€èšããŸãã
1. FETCH_ADVANCE_INST ïŒ2ïŒæ¬¡ã®ãªãã³ãŒããrINSTã¬ãžã¹ã¿ã«æžã蟌ãŸããŸã
2. ipã¬ãžã¹ã¿ã®GET_INST_OPCODE ïŒipïŒã«ãªãã³ãŒãçªå·ãå ¥åããŸãïŒãã§ã«æ¬¡ïŒ
3. GOTO_OPCODE ïŒipïŒæ¬¡ã®ãªãã³ãŒãã®ã³ãŒãã«ç§»åããŸã
ããã3ã€ã®ã³ãã³ãã§ã¯ãrIBASEã¬ãžã¹ã¿ã衚瀺ãããŸãã çªå·ã0x00ã®ãªãã³ãŒããã©ããã確èªããå¿ èŠããããŸããïŒ ã©ãããããã ã ã¯ããããã§ãã å€ãã®å Žåãã³ãŒãã«ã¯æ¬¡ã®è¡ããããŸãã
adr rIBASE, dvmAsmInstructionStart @ set rIBASE
ãŸãã dvmAsmInstructionStartã®å€ã¯.L_OP_NOPã§ãã OP_NOPã³ãŒãã¯ã©ãã§ããïŒ æ¬åœã«0x00ã§ãã
èæ ®ããªãã£ãããç§ã¯ããã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãä»ã®åæïŒrPCãrFPïŒã¬ãžã¹ã¿ã®å 容ã®ã¿ãèæ ®ããŸããã§ããã ããããç§ãã¡ã¯ããããããã«æ€èšããŸãã ãªãããããå¯èœããªã®ãããããŸã§ã®ãšããrPCã§ã¯ãªãrFPã倧ããªäŸ¡å€ãããããã§ãã
è¿œå ãªãã³ãŒãã調ã¹ãïŒæ£ããããŒãžã§ã³ïŒ
ãªãã³ãŒãã®æ€æ»æ¹æ³ã¯å®å šã«æ£ãããšã¯æããŸããã§ããããç§ã«ãšã£ãŠã¯ããå¿«é©ã«æããŸããã ããããä»åºŠã¯ãããã©ã®ããã«æ¹åã§ããããã€ãŸãarm5vteãã©ã«ããŒå ã®ãã¡ã€ã«ã¯ã©ã®ããã«æ§æãããŠããã®ããèŠãŠã¿ãŸãããã
ãããè¡ãã«ã¯ã README.txtããã¥ã¡ã³ããåç §ããŠãã ããã
å°ãé©ããŠããŸãããç 究ã«äœ¿çšããæ¹æ³ã¯README.txtãã¡ã€ã«ã®èŠ³ç¹ããã¯æ£ãããã®ã§ããã åŒçšã¯ããã«ãããŸãïŒ
ãã€ã³ã¿ãŒããªã¿ãŒã«æ £ããæåã®æ¹æ³ã¯ãarmv5teã®ããŸããŸãªã³ã³ããŒãã³ãã調ã¹ãã®ã§ã¯ãªããout / InterpC-portstd.cãªã©ã®outãã£ã¬ã¯ããªã§çæããããã¡ã€ã«ã調ã¹ãããšã§ãã ã
ããã§ãäŸãšããŠããã¡ã€ã«OP_ADD_INS.SãèããŸãã
%verify "executed" %include "armv5te/binop.S" {"instr":"add r0, r0, r1"}
ãã®ã³ãŒãã¯ããã®ãã¡ã€ã«ãæ¡ä»¶ä»ãã§binop.Sãã¡ã€ã«ã«çœ®ãæãããã$ instrã®å€ã«
add r0, r0, r1
ã
add r0, r0, r1
ãããããš
add r0, r0, r1
æå³ããŸãã
binop.Sãã¡ã€ã«ãæ€èšããå¿ èŠããããŸãã
%default {"preinstr":"", "result":"r0", "chkzero":"0"} /* * Generic 32-bit binary operation. Provide an "instr" line that * specifies an instruction that performs "result = r0 op r1". * This could be an ARM instruction or a function call. (If the result * comes back in a register other than r0, you can override "result".) * * If "chkzero" is set to 1, we perform a divide-by-zero check on * vCC (r1). Useful for integer division and modulus. Note that we * *don't* check for (INT_MIN / -1) here, because the ARM math lib * handles it correctly. * * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int, * xor-int, shl-int, shr-int, ushr-int, add-float, sub-float, * mul-float, div-float, rem-float */ /* binop vAA, vBB, vCC */ FETCH(r0, 1) @ r0<- CCBB mov r9, rINST, lsr #8 @ r9<- AA mov r3, r0, lsr #8 @ r3<- CC and r2, r0, #255 @ r2<- BB GET_VREG(r1, r3) @ r1<- vCC GET_VREG(r0, r2) @ r0<- vBB .if $chkzero cmp r1, #0 @ is second operand zero? beq common_errDivideByZero .endif FETCH_ADVANCE_INST(2) @ advance rPC, load rINST $preinstr @ optional op; may set condition codes $instr @ $result<- op, r0-r3 changed GET_INST_OPCODE(ip) @ extract opcode from rINST SET_VREG($result, r9) @ vAA<- $result GOTO_OPCODE(ip) @ jump to next instruction
ã芧ã®ãšãããã³ãŒãã¯ä»¥åãšéåžžã«ãã䌌ãŠããŸãã ä»ããç解ã§ããªãç¬éã¯æ®ã£ãŠããŸããã ããšãã°ãã@ optional op ..ããšããã³ã¡ã³ãããããŸãããããã®çç±ã¯æããã§ã¯ãããŸããã ä»ã§ã¯æããã§ãã
ãã®ãªãã³ãŒããå解ããããšã«ã¯æå³ããããŸããããã¹ãŠããã§ã«èæ ®ãããŠããŸãã ããã§ãæãéèŠãªè³ªåã«ãã°ããé²ãå¿ èŠããããŸãããã€ãã£ãé¢æ°ãšéãã€ãã£ãé¢æ°ã®åŒæ°ã¯ã©ã®ããã«åã蟌ãŸããŸããïŒ
ããŒãII ãŸãšã
ããã¯ãã§ã«æåã®éšåãšã¯ç°ãªãã¬ãã«ã§ãããç§ã¯å€ããåŠã³ãèŠããŠããªããã°ãªããŸããã§ãããããªãã³ãŒãã®æ§é ã¯æ確ã«ãªããŸããïŒ æ¥œãããŸãã ã¯ããããã«åã³ãæããããšã»ã©å€§ããªæå³ã¯ãããŸããã ãã ããåæã«ããã§ã«ãªãã³ãŒããäœæã§ããŸãã
ãã®éšåããããã¡ã€ã«ãçæããããã«äœ¿çšãããã¢ãŒããã¯ãã£ãåŠç¿ã§ããŸãã é©åãªãªãã³ãŒããèŠã€ããå Žæãšæ¹æ³ã
ãŸããå€ãã®è³ªåããããããããŸãããéçºè ã®Dalvik VMã®ãã¬ãŒã³ããŒã·ã§ã³ãèŠãããšããå§ãããŸãããã®ãã¬ãŒã³ããŒã·ã§ã³ã§ã¯ãGOTO_OPCODEãªã©ã®ã³ãã³ããã©ã®ããã«äœ¿çšãããŠãããããŸãã¯ãã€ãã³ãŒããã¥ãŒãã©ã®ããã«ç·šæãããŠããããéåžžã«ãã瀺ããŠããŸãã
ç®æšã«ã€ããŠããã«çµè«ãåºãã€ããã¯ãããŸããããã¹ãŠã®çµè«ã¯èšäºã®æåŸã«ãªããŸãããããŠä»ãDalvik VMã®å éšã«é£ã³èŸŒãã§ããã®ã³ãŒããå®è¡ãããå Žæãç解ããããšãææ¡ããŸãããã¬ãã«ãããã«é«ããªããšèŠåããŸãããæ¿å ¥ããã³ãŒãã¯å°ãªãããŸãã
ããŒãIIIãã³ãŒãã¯ã©ã®ããã«ãã©ãã§å®è¡ãããŸããïŒ
第3éšã§ã¯ãDalvik VMã§é¢æ°ãæœåºããããã»ã¹ã«ã€ããŠèª¬æããŸãã以åã®ç¥èã¯å€§ãã«åœ¹ç«ã¡ãŸãããé£èºã¯ç¬¬1éšãšç¬¬2éšã®éãšåãã§ãããšä»®å®ããã®ã¯æãã§ããããå§ããŸãããïŒ
泚ïŒããã«ãªã³ã¯ããã©ãã®ã§ã¯ãªããæåã«èªãããšããå§ãããŸãããã®ãããè³æã¯åŸã ã«è¡šç€ºãããæ··ä¹±ããå¯èœæ§ã¯äœããªããŸãã
å解ãã
ãªãã³ãŒããã©ã®ããã«èªã¿èŸŒãŸããããç解ããå¿ èŠããããŸãããã®ããããã®ãããªã»ã¯ã·ã§ãã«ã³ãŒããèŠãŠãããŸãã
public class Summator { void test() { sum(44, 43); staticSum(42, 41); nSum(44, 43); nStaticSum(42, 41); } int sum(int a, int b) { return a + b; } static int staticSum(int a, int b) { return a + b; } native int nSum(int a, int b); native static int nStaticSum(int a, int b); }
name : 'test' type : '()V' access : 0x0000 () code - registers : 5 ins : 1 outs : 3 insns size : 21 16-bit code units outs : 3 insns size : 21 16-bit code units 0022a8: |[0022a8] com.m039.study.Summator.test:()V 0022b8: 1303 2c00 |0000: const/16 v3, #int 44 // #2c 0022bc: 1302 2b00 |0002: const/16 v2, #int 43 // #2b 0022c0: 1301 2a00 |0004: const/16 v1, #int 42 // #2a 0022c4: 1300 2900 |0006: const/16 v0, #int 41 // #29 0022c8: 6e30 2e00 3402|0008: invoke-virtual {v4, v3, v2}, Lcom/m039/study/Summator;.sum:(II)I // method@002e 0022ce: 7120 2d00 0100|000b: invoke-static {v1, v0}, Lcom/m039/study/Summator;.staticSum:(II)I // method@002d 0022d4: 6e30 2600 3402|000e: invoke-virtual {v4, v3, v2}, Lcom/m039/study/Summator;.nSum:(II)I // method@0026 0022da: 7120 2500 0100|0011: invoke-static {v1, v0}, Lcom/m039/study/Summator;.nStaticSum:(II)I // method@0025 0022e0: 0e00 |0014: return-void catches : (none) positions : 0x0008 line=29 0x000b line=30 0x000e line=31 0x0011 line=32 0x0014 line=33 locals : 0x0000 - 0x0015 reg=4 this Lcom/m039/study/Summator;
ç§ã¯æ¬åœã«armv5teãã£ã¬ã¯ããªå ã®ãã¹ãŠã®ãã¡ã€ã«ã解æïŒããã³èšäºã«ã³ããŒïŒããããããŸããããããã£ãŠããããã®ãã¡ã€ã«ãããªã³ã¯ãšæç²ãæäŸããããšããŸãã
äžèšã®ãªã¹ããèŠããšããã€ãã£ãã¡ãœããã«éãã¯ãªãããšãããããŸããã©ãããŠïŒå®éã«ã¯ããã§ããã¯ãã§ããããšã«ããããªã¹ãã«ã¯ãã€ãã£ãã¡ãœãããã©ã®ããã«æœåºããããã®ãã³ãã¯ãããŸããã
ããããæåã«ãåŒã³åºãèªäœïŒinvoke-virtualïŒãèæ ®ãããããã«ããã«ããã³ãŒããå°ãããªããšä»®å®ããŠãã ãããïŒãããã£ãŠãç§ãã¡ã¯ããã«èŠã€ããããã®ãäºåã«åœ¢æãã
ä»®æ³éçã®ã³ã³ãã©ã¹ã-
-èªå·±è§£åæ©èœ
ã®ã¢ã¯ã·ã§ã³ãæœåºããããã«ã次ã«ã©ã®ãããªå¯èœæ§ããã©ã®ãããã®ããããŠ-
ããªããèå³ãæã£ãŠãããšã®ç 究ãæãªãã¹ãã§ã¯ãªããŸã§ãæ®ããã
ã¡ãœããå®è¡
ãªã¹ããäžããäžã«èŠãŠãããŸãããã
sumã¡ãœãããå ¥åããã³ååŸããã³ãŒãã®äžéšïŒ
0022b8: 1303 2c00 |0000: const/16 v3, #int 44 // #2c 0022bc: 1302 2b00 |0002: const/16 v2, #int 43 // #2b 0022c8: 6e30 2e00 3402 |0008: invoke-virtual {v4, v3, v2}, Lcom/m039/study/Summator;.sum:(II)I // method@002e
äžèŠããã¹ãŠãéåžžã«ç°¡åã§ããé©åãªã¬ãžã¹ã¿ãå ¥åãããã¡ãœãããååŸãããŸãã
ãã®æ¹æ³ãå éšããã©ã®ããã«èŠããããææ¡ããããšæããŸãã
const/16
-ããããæ°å€0ã§å€44ãä»®æ³ã¬ãžã¹ã¿ã«å ¥ãã次ã«å€43ãå ¥ããŸãïŒæ³šïŒv1ãä»®æ³ã¬ãžã¹ã¿ã®æå®ã§ãããšä»®å®ããå Žåãçãã¯ãããŸããïŒ
invoke-vritual
-ãã®å€ãv4ã«å ¥ããŠé¢æ°ãåŒã³åºããŸãã
const / 16
%verify "executed" /* const/16 vAA, #+BBBB */ FETCH_S(r0, 1) @ r0<- ssssBBBB (sign-extended) mov r3, rINST, lsr #8 @ r3<- AA FETCH_ADVANCE_INST(2) @ advance rPC, load rINST SET_VREG(r0, r3) @ vAA<- r0 GET_INST_OPCODE(ip) @ extract opcode from rINST GOTO_OPCODE(ip) @ jump to next instruction
ãã®ã³ãŒãã¯ã2çªç®ã®ãã€ãã§éä¿¡ãããå€ãèªã¿åãããã®å€ãä»®æ³ã¬ãžã¹ã¿ã«æžã蟌ã¿ãŸããïŒåã³ïŒãã¹ãŠãçæãããCã³ãŒãïŒæé©åãããããŒãžã§ã³ïŒãšåãããã«èŠããŸããã2ã€ã®è¿œå ã ãããããŸãïŒæžã蟌ã¿/èªã¿åãããšã«äžéä»®æ³ã¬ãžã¹ã¿ã䜿çšãããæ¯åæ°ãããªãã³ãŒããããŒããããé·ç§»ãè¡ãããŸããããã§ãªããã°ããã¹ãŠãéåžžã«éæã§ãã
åŒã³åºãçš®é¡
2ã€ã®ä»®æ³ã¬ãžã¹ã¿ããã£ã±ãã§ãããã¡ã€ã«OP_INVOKE_VIRTUAL.Sã«ç§»åããŠãã ããããããŠãæ·±ãææããããŸãããã®ãããä»®æ³ïŒãã¡ã€ã«OP_INVOKE_VIRTUAL.SïŒãšéçïŒOP_INVOKE_STATIC.SïŒã®éããããã«ç解ããããšããŸãã
ã³ãŒãã«ãããšãéãã¯2ã€ã®å Žæã«ãããŸããéçã¡ãœããã§ã¯ãªãdvmResolveMethodé¢æ°ã«æž¡ãããå€ã«ã¯ãè¿œå ã®ã.L $ {opcode} _continueïŒããè¿œå ãããŸãã
dvmResolveMethodé¢æ°ã®æ©èœãæ€èšããŠãã ããã
ãã®é¢æ°ãåŒã³åºãåã«ãã¬ãžã¹ã¿ã¯æ¬¡ã®ããã«åããããŸãã ïŒã³ã¡ã³ãããã®æç²ïŒïŒ
-r0 <-method-> clazz
-r1 <
-Priv * -r2 <-METHOD_VIRTUALãŸãã¯METHOD_STATICïŒmethod typeïŒ
-r3 <-glue-> method
*ææžã«ããåœä»€åœ¢åŒ PrivãBBBBã¯ã³ã¡ã³ãã«èšè¿°ãã
ãŠããŸãããä»åºŠã¯dvmResolveMethodé¢æ°ã®ã³ãŒãã«æ»ããŸããé¢æ°ã®å®£èšãèŠããšã4çªç®ã®åŒæ°ïŒäžèšãåç §ïŒãäžèŠã§ããããšãæããã«ãªããŸãã
Method* dvmResolveMethod(const ClassObject* referrer, u4 methodIdx, MethodType methodType)
ãã®é¢æ°ã¯Methodæ§é äœãžã®ãã€ã³ã¿ãŒãè¿ããŸãããã®é¢æ°ã«ã€ããŠè©³ããç¥ãå¿ èŠã¯ãããŸããããã®æ§é ãèŠãŠãã ããã
èå³æ·±ãæçšãªåéããããããããŸãããç¹å¥ãªé¢å¿ãæäŸããçŽ æŽãããåéããããŸã-
nativeFunc
ããããã£ãŠããã®æ§é ã«ã¯ãã€ãã£ãé¢æ°ãžã®ãã€ã³ã¿ãå«ãŸããŸãã
ããã§ããã®æ§é ãŸãã¯ãã®ã¡ãœããããå®è¡äžãã®å ŽæãèŠã€ããŠãããšããã§ãããã
OP_INVOKE_STATIC.Sãã¡ã€ã«ãšOP_INVOKE_VIRTUAL.Sã®äž¡æ¹ã§ãé¢æ°ã¯æåŸã«åŒã³åºãã
bl common_invokeMethod${routine}
ãŸããã»ãšãã©ã®å Žåãããã¯Methodæ§é ã®ã¡ã€ã³ãã³ãã©ãŒã§ããããã®ã³ãŒãã¯footer.Sãã¡ã€ã«ã«ãããŸãããã¬ãã£ãã¯ã¹ãNoRangeãã¯ããã¡ã€ã«ã®æåã®è¡ã®ããã«è¡šç€ºãããŸãã-
%default { ... , "routine" : "NoRange" }
ããããfooter.SãèŠãåã«ãã¿ã€ãã®æå³ã確èªã§ããŸã
DalvikBridgeFunc
ãã£ãŒã«ãã§
nativeMethod
ïŒ VMã³ãŒããå®è¡ãããš
nativeMethod
ãdvmResolveNativeMethod é¢æ°ããã£ãŒã«ãã«å²ãåœãŠãããŠããããšãããããŸãã
ãã®é¢æ°ã®ã³ã¡ã³ãããããã€ãã£ãã¡ãœããïŒã©ã€ãã©ãªlibNAME.soå ïŒãæ€çŽ¢ããæãéèŠãªå®è¡ã«äœ¿çšãããããšãæããã«ãªããŸããããã§åœŒå¥³ã®èšèãèããŠã¿ãŸãããããã®å Žåã¯ãããä¿¡ããã®ãå¯äžã®å Žåã§ãã
ãã1ã€è³ªåããããŸããããã€ãã£ãã¡ãœãããå®è¡ãããŠãŒã¶ãŒãšå Žæãæ確ã«ãªããŸãããããããããã§ããã©ãã§å®å šã«æ確ã§ã¯ãããŸãããçµå±ãfooter.Sãã¡ã€ã«ã¯ã¬ãã¥ãŒãããŸããã§ãããcommon_invokeMethodNoRange
é¢æ°ã«æ»ããéåžžã«æããããæåŸã®éšåã§æ確ã§ã¯ãªãã£ããã®ãã€ãŸãrFPãrPCãªã©ã®ã¬ãžã¹ã¿ãŒãèšå®ããŠããã®ã¯èª°ãªã®ããšããçããå«ãŸããŠããããšã«æ³šæããŠãã ãããã芧ã®ãšããããã®é¢æ°ã¯ããããåããŸãã
ã»ãã®å°ãã®å¿èããããŠãããšãã°ãrINSTãrPCãr2ãäœã§æºããããŠããããç解ã§ããŸããïŒ method-> instãã£ãŒã«ããžã®ãã€ã³ã¿ãŒãã€ãŸãåœä»€ïŒãã€ãã³ãŒãïŒããããŠããã®ãããªç¬éãããããããã®ã§ãããããçç¥ããŸãã
ãããããã€ãã£ãã¯èå³ãããããã¹ãŠãããã«ç°¡åã§ããã¡ãœããããã€ãã£ãã®å ŽåïŒå¯Ÿå¿ãããã©ã°ããã§ãã¯ãããŠããå ŽåïŒãæ¢ã«åŠçããã®ãšåãnativeFuncé¢æ°ãå®è¡ãããŸãã
ãã以å€ã®å Žåãcommon_invokeMethodNoRangeã¯ä»¥åã«èª¿ã¹ãæšæºãªãã³ãŒããšéåžžã«ãã䌌ãŠããŸããè¿œå ã®ãã§ãã¯ã¯å€ããããŸãã
ããããéçãŸãã¯ééçã¡ãœããã¯ã©ãã§ããããïŒfooter.Sã¯ãã©ãããããããšã¯äœã®é¢ä¿ããããŸããããããã«ã€ããŠèšããããšã¯ãã¹ãŠã察å¿ãããªãã³ãŒããã¡ã€ã«ïŒinvoke-virtualããã³invoke-staticïŒã§ãã§ã«è¿°ã¹ãããŠããŸãã
ããã«ã€ããŠã誰ãã©ãã§äœãäœæããããæ確ã«ããããšãã§ããŸããããã§ãªãå Žåãããã«ç解ããããšã¯é£ãããããŸãããç§ã®ä»äºã¯ã質åãããããšïŒå ã®ç®æšãåç §ïŒã瀺ãããããå®éãããããç解ããããšã§ãã
ããŒãIIIã ãŸãšã
ãã®éšåã§ã¯ããã€ãã£ãã¡ãœããã®ååŸãæ åœããé¢æ°ãèŠã€ãããŸããããŸãããã®é¢æ°ãååŸãããå Žæãšä¿åãããå Žæã远跡ããŸããããã®ç¥èãããã°ãJavaèšèªã®ä»ã®éšåãèŠãŠãDalvik VMã³ãŒãã§ãããã芳å¯ã§ããŸãã
ãã®ããŒãã®åŸããã€ãã³ãŒãã¯å€ãã®ãªãã³ãŒãã§ããããããããçžäºã«äœçšããããšãæããã«ãªããŸãããããŠããã®éšåã§ã¯ããã®çžäºäœçšã®ããäžéšã®ã¿ãèæ ®ãããŸããã
ãã®ãããã¯ã«èå³ãããå Žåã¯ãå°æ¥çã«ã¯éã¢ã»ã³ãã«ããã圢åŒã®Javaèšèªã®æšæºæ§é ãæ€èšãããã¬ãŒã³ããŒã·ã§ã³ã§éçºè ã®Dalvik VMãAndroidçšã®Javaèšèªã§ããã°ã©ãã³ã°ãããšãã«è¡ãã¹ããŸãã¯ãã¹ãã§ãªãäŸã瀺ããçç±ãç解ã§ããŸãã
ãŸãšã
ããã§ã¯ããã®èšäºã§èŠã€ããããšãã§ãããšæããããã®ããæç²ããããšããŸãã
ããããæåã«ãèšäºãã©ã®ããã«ã³ã³ãã€ã«ããããã«ã€ããŠã®ããã€ãã®æ©èœã匷調ããããšæããŸãã
ããã¹ãã§ãåèããšããèšèã«åºãããããããããŸãããããã¯ããã©ããã§èšäºå šäœãæžããåŸã«è¿œå ãããŸããããããŠããããã®ã³ã¡ã³ããè¿œå ãã䟡å€ãããããã«æããŸããã
ãã®èšäºã®ç§ã®ç®æšã¯ããããŸããªã³ãŒããå®éã«ç 究ããããã«å¿ èŠãªèãæ¹ã瀺ãããšã§ããç§ã¯éåžžã«ç°¡åãªè³ªåãšããã®ããã«èå³ã®ãããªããžã§ã¯ããéžæããŸããããããã£ãŠãå€ãã®æ¯éšã«äŒã£ãŠãäž»é¡ã«å¯Ÿããæ 床ãã©ã®ããã«å€åãããã«æ°ä»ãããšãã§ããŸãã
ãããŠä»ãç§ã«ãšã£ãŠèå³æ·±ããšæãããããšããããŠç 究ã®çµæã«ã€ããŠå°ã説æããŸãã Javaèšèªä»æ§ã«ã¯å€ãã®ããšãæžãããŠããŸããããã®èšäºã®åŸã§ã¯ããããã®æ§é ããã®ãŸãŸç解ããæ¹ãã¯ããã«ç°¡åã§ãã
äž»ãªãã€ã³ãã¯æ¬¡ã®ãšãã
ã§ãã1.ã¡ãœããåŒã³åºãã¯ãéçãä»®æ³ïŒã¯ã€ãã¯ãã¬ãã£ãã¯ã¹ãå«ãïŒãäœã§ãããã¡ãœããåŒã³åºãã§ãããåçŽãªCïŒããã³C ++ïŒãšæ¯èŒããå Žåãããèªäœéåžžã«è€éã§ããããšãã°ãBox2Dã®ã©ãããŒããããšããŸãããªããžã§ã¯ãã亀差ãããã©ããããã§ãã¯ããããã«æ¯åïŒç¡éã«ãŒãã§ïŒã¡ãœããããã®ã©ãããŒããåŒã³åºããããšã察å¿ãã質åãçºçããŸã-ãªãã§ããïŒããã¯Cã§è¡ãå¿ èŠããããŸãããJavaã§ã¯ãŒã«ããäœæããŠãªããžã§ã¯ããåæåã§ããŸãã
2.ãªãã³ãŒãã®æ©èœã¯ã¢ã»ã³ãã©ãŒã®æ¿å ¥ã«éåžžã«è¿ãããããªãã³ãŒãã¯ã¢ã»ã³ãã©ãŒã䜿çšããŠå®è£ ãããŸããåœç¶ããããã¯JNIãä»ããŠãµãŒãããŒãã£é¢æ°ãåŒã³åºããããåªããŠããŸãããCã§ãããè¡ããããæªãã§ã
ã2ã€ã®åºæºã«ãã£ãŠæªåããŸã
ã1ïŒåŒã³åºãã«ä»®æ³ã¬ãžã¹ã¿ãä»ããŠã©ãããŒã䜿çšããŸããã¢ãŒãããªãã³ãŒãã®é床ã¯Cã®æé©åãããŠããªãããŒãžã§ã³ãšéåžžã«äŒŒãŠãããšããèšããŸã
ã2ïŒåãªãã³ãŒãã«ã¯æ¬¡ã®ãªãã³ãŒããååŸããã³ãŒãããããŸãããããã»ã©å€§ããã¯ãããŸãããæœåºåŸããã§ã«ç°¡åãªæ瀺ã®ããã«èŠãã次ã®ãã®ãžã®ç§»è¡ãè¡ãã
bl
ãŸãã
ç§ã¯èå³ã倱ããç§ãæãã§ããããšãç¥ããç§ã®æšæž¬ã¯ã»ãšãã©æ£åœåãããŸãããããªããããã奜ãã§ãããªããç§ãšäžç·ã«ãã®ããã«è¡ã£ããªããç§ã¯éåžžã«å¬ããæããŸããèå³æ·±ãèããšããã¹ãŠãã©ã®ããã«æ©èœãããã«äž»ãªé¢å¿ãããããšãé¡ã£ãŠããŸãã
éçºè ã¯ã¹ãã¬ãªã¿ã€ãïŒJavaãšC / C ++ã«é¢ããŠïŒãéåžžã«é »ç¹ã«äœ¿çšããããããç Žå£ããããã®ããããªã¢ã¯ã·ã§ã³ãã©ãã«ã衚瀺ããªãããšã«ãã°ãã°æ°ã¥ããŸãã
ããªãã¯è¿œå ã®ææã«èå³ãããå Žåã¯ããã¡ã€ã«ã®docsãã©ã«ãã«èŠãããšãã§ããŸãJNI-tips.htmlãšã®ãã¬ãŒã³ããŒã·ã§ã³ 2008ããããããŒDavik VMãèå³æ·±ãsmaliãããžã§ã¯ãããããŸãããç§ã®æã«ã¯å±ããŸããã§ããã
PSããã«è¬çœªããŸããééããå Žåã¯ä¿®æ£ããŠãã ãããããã«å€æŽãå ããŸãã