2012-12-31 2 views
5

मैं स्माली सीखने की कोशिश कर रहा हूं और मेरे पास कुछ सवाल है कि मैं उन्हें गुगल करके नहीं ढूंढ पाया।DalvikVM कैसे स्विच करता है और स्माली कोड

1) मैं एक साधारण परीक्षण का मामला बनाया बेहतर अपने आप

const-string v1, "Start" 
:try_start_0 
const-string v1, "Try Block" 
invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V 
:try_end_0 
.catchall {:try_start_0 .. :try_end_0} :catchall_0 

.catch बयान की व्याख्या करने के लिए: दो तर्क दो लेबल के बीच कोड उस लेबल तक कि लेबल से लेते हैं और उसे पकड़ने का क्या मतलब है () या इसका मतलब यह है कि कोशिश करने का प्रयास करना प्रारंभ करें: try_start_0 तक पहुंचने तक: try_end_0 (दो लेबल के भीतर कोड निष्पादित करने के लिए गोटो कूदने की अनुमति देता है)?

क्या लेबल हमेशा try_start_% d प्रारूप में कोशिश करने के लिए है या क्या वे कोई लेबल हो सकते हैं?

2) एक और मामला

packed-switch v0, :pswitch_data_0 

const-string v1, "Default Case" 

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V 

:goto_0 

const-string v1, "The End" 

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V 

return-void 

:pswitch_0 
const-string v1, "Case 1" 

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V 

goto :goto_0 

:pswitch_data_0 
.packed-switch 0x1 
:pswitch_0 
.end packed-switch 

स्विच बयान: यह आवश्यकता होती है कि स्विच बयान स्विच डेटा और स्विच कॉल के बीच झूठ? और फिर भी सुविधा के लिए तय किए गए लेबल का नामकरण या बस?

3) यदि लेबल अलग-अलग हो सकते हैं, तो क्या बाक्समाली कभी भी विभिन्न लेबलों के साथ स्माली कोड उत्पन्न करेगा?

4) वैकल्पिक रेखाएं क्या हैं जिन्हें हमेशा डीईक्स को अपनाने पर दिखाया नहीं जाता है?

मुझे पता है .parameter और .line वैकल्पिक हैं, लेकिन क्या वे सभी नहीं हो सकते हैं?

अग्रिम धन्यवाद।

उत्तर

4

1)

पहले दो लेबल (try_start_0 और अपने उदाहरण में try_end_0) कोड है कि कोशिश ब्लॉक कवर की सीमा निर्धारित करते हैं। यदि एक अपवाद कवर कोड के भीतर होता है, तो निष्पादन तत्काल तीसरे लेबल (catchall_0) पर कूद जाता है। लेबल का नाम महत्वपूर्ण नहीं है, यह कोई मान्य पहचानकर्ता हो सकता है।

। कैच निर्देश भी है, वही बात है, सिवाय इसके कि यह केवल एक विशिष्ट प्रकार का अपवाद (जावा के पकड़ विवरण के समान) को संभालता है।

कोड का एक ब्लॉक एकाधिक पकड़ विवरणों द्वारा कवर किया जा सकता है, और अधिकतर 1 में सभी कथन को पकड़ें। .catch कथन का स्थान महत्वपूर्ण नहीं है, हालांकि, एक ही कोड को कवर करने वाले कैच स्टेटमेंट का सापेक्ष आदेश आयात है। उदाहरण के लिए, यदि आपके पास

.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :handler1 
.catch Ljava/lang/RuntimeException; {:try_start_0 .. :try_end_0} :handler2 

दूसरा कैच स्टेटमेंट कभी भी उपयोग नहीं किया जाएगा। यदि कवर कोड में एक रनटाइम अपवाद फेंक दिया जाता है, तो पहली पकड़ हमेशा उपयोग की जाएगी, क्योंकि रनटाइम अपवाद एक अपवाद है।

हालांकि, अगर वे विपरीत क्रम में थे, तो यह आपके जैसा काम करेगा - रनटाइम अपवादक हैंडलर को रनटाइम अपवादों के लिए उपयोग किया जाता है, और अपवाद हैंडलर किसी अन्य प्रकार के अपवाद के लिए उपयोग किया जाता है।

और अंत में, जावा के विपरीत, .catch कथन में कोड की सीमा को सख्ती से घोंसले की आवश्यकता नहीं है। उदाहरण के लिए,

:a 
const-string v1, "Start" 
:b 
const-string v1, "Try Block" 
:c 
invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V 
:d 
.catch Ljava/lang/RuntimeException; {:a .. :c} :d 
.catch Ljava/lang/Exception; {:b .. :d} :d 

कुछ ऐसा करने के लिए यह पूरी तरह कानूनी है, इस तरह आप कुछ सुंदर अजीब निर्माण भी कर सकते हैं।

.method public static main([Ljava/lang/String;)V 
    .registers 3 

    :second_handler 
    :first_try_start 
     new-instance v0, Ljava/lang/RuntimeException; 
     invoke-direct {v0}, Ljava/lang/RuntimeException;-><init>()V 
     throw v0 
    :first_try_end 
    .catch Ljava/lang/Exception; {:first_try_start .. :first_try_end} :first_handler 
    :first_handler 
    :second_try_start 
     new-instance v0, Ljava/lang/RuntimeException; 
     invoke-direct {v0}, Ljava/lang/RuntimeException;-><init>()V 
     throw v0 
    :second_try_end 
    .catch Ljava/lang/Exception; {:second_try_start .. :second_try_end} :second_handler 
.end method 

उपरोक्त उदाहरणों में से न तो कभी संकलित जावा कोड से उत्पन्न किया जा सकता है, लेकिन बाईटकोड ही यह अनुमति देता है।

2) स्विच स्टेटमेंट स्विच स्टेटमेंट या स्विच डेटा के संबंध में कहीं भी हो सकता है। यहां लेबल नाम मनमानी भी हैं।

3) Baksmali 2 तरीकों में से एक में लेबल उत्पन्न कर सकते हैं। डिफ़ॉल्ट तरीका लेबल के सामान्य "प्रकार" का उपयोग करना है, और लेबल के बाइटकोड पते को जोड़ना है। यदि आप बाइटकोड पते का उपयोग करने के बजाय -s/- अनुक्रमिक-लेबल विकल्प निर्दिष्ट करते हैं, तो यह प्रत्येक लेबल प्रकार के लिए काउंटर रखता है और प्रत्येक बार जब वह उस प्रकार का लेबल उत्पन्न करता है तो इसे बढ़ाता है।

4) आम तौर पर कुछ भी जो डीबग जानकारी का हिस्सा है। .parameter, .line, .prologue, .epilogue, .source, .local, .restart स्थानीय, स्थानीय स्थानीय ... मुझे लगता है कि इसे कवर करने के बारे में।

+0

धन्यवाद। यह वही है जो मैं जानना चाहता था। मैं विशेष रूप से अपने दूसरे "अजीब" निर्माण पसंद है :)। मुझे पता है कि संकलित जावा कोड इसे देने में सक्षम नहीं होगा, लेकिन एक अनुकूलन प्रोग्राम कोड को उस राज्य में अनुकूलित करने में सक्षम होगा जो नियमित जावा कोड के साथ प्राप्त नहीं हो सकता है (थोड़ा सी/सी ++ गोटो जैसे "अजीब" बहाव को काबू करें) ? – Xonar

+0

एक अनुकूलक - संभवतः नहीं। हालांकि, यह एक obfuscator से अधिक संभावना हो सकती है – JesusFreke

संबंधित मुद्दे