2013-04-17 4 views
7

मैं कुछ संकलित स्क्रिप्ट (.pyc) को फिर से लिखने के लिए 'dis' मॉड्यूल का उपयोग कर रहा हूं। मैं JUMP_FORWARD और JUMP_ABSOLUTE के बीच अंतर को समझता हूं। मेरी जानकारी के लिए एक अगर बयान एक JUMP_FORWARD द्वारा बंद कर दिया जाएगा:JUMP_FORWARD या JUMP_ABSOLUTE? पाइथन 2.5

>>> def f(): 
     if a: 
       print '' 
>>> from dis import dis 
>>> dis(f) 
    2   0 LOAD_GLOBAL    0 (a) 
       3 JUMP_IF_FALSE   9 (to 15) 
       6 POP_TOP    

    3   7 LOAD_CONST    1 ('') 
      10 PRINT_ITEM   
      11 PRINT_NEWLINE  
      12 JUMP_FORWARD    1 (to 16) 
     >> 15 POP_TOP    
     >> 16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE  

और अगर अगर बयान एक और पाश के अंत में है JUMP_ABSOLUTE दिखाई देगा। उदाहरण के लिए:

if a<100 and b>10: 
      ok=1 
:

121   228 LOAD_FAST    11 (a) 
      231 LOAD_CONST    9 (100) 
      234 COMPARE_OP    0 (<) 
      237 JUMP_IF_FALSE   23 (to 263) 
      240 POP_TOP    
      241 LOAD_FAST    11 (b) 
      244 LOAD_CONST    11 (10) 
      247 COMPARE_OP    4 (>) 
      250 JUMP_IF_FALSE   10 (to 263) 
      253 POP_TOP    

122   254 LOAD_CONST    3 (1) 
      257 STORE_FAST    4 (ok) 
      260 JUMP_ABSOLUTE   27 
     >> 263 POP_TOP  

मैं कोड लगता होगा निम्नलिखित है:

>>> def f1(): 
    if a: 
     if b: 
      print '' 
>>> dis(f1) 
    2   0 LOAD_GLOBAL    0 (a) 
       3 JUMP_IF_FALSE   20 (to 26) 
       6 POP_TOP    

    3   7 LOAD_GLOBAL    1 (b) 
      10 JUMP_IF_FALSE   9 (to 22) 
      13 POP_TOP    

    4   14 LOAD_CONST    1 ('') 
      17 PRINT_ITEM   
      18 PRINT_NEWLINE  
      19 JUMP_ABSOLUTE   27 
     >> 22 POP_TOP    
      23 JUMP_FORWARD    1 (to 27) 
     >> 26 POP_TOP    
     >> 27 LOAD_CONST    0 (None) 
      30 RETURN_VALUE   

Bytecode मैं वापस कोड लिखने के लिए पढ़ रहा हूँ से, वहाँ एक JUMP_ABSOLUTE है कि मुझे आश्चर्य है

लेकिन यह एक JUMP_FORWARD को उत्तेजित करता है, न कि JUMP_ABSOLUTE। मुझे पता है कि यह एक WHILE लूप नहीं है, न ही एक फोर स्टेटमेंट क्योंकि वे दोनों बाइटकोड में एक SETUP_LOOP लाइन बनाते हैं।

मेरा सवाल है: मुझे क्या याद आ रही है? मैं ABSOLUTE कूद के बजाय एक फॉरवर्ड क्यों प्राप्त करूं?

संपादित करें: एक (? जबकि) पाश की शुरुआत है, जिसमें इन दो पंक्तियों 121 और 122 से संबंधित 27 अंक सूचकांक करने के लिए पूर्ण कूद:

106   24 SETUP_LOOP    297 (to 324) 
     >> 27 LOAD_FAST    4 (ok) 
      30 LOAD_CONST    1 (0) 
      33 COMPARE_OP    2 (==) 
      36 JUMP_IF_FALSE   283 (to 322) 
      39 POP_TOP 

वहाँ से पहले और एक अन्य एक अगर बयान है इन लाइनों के बाद एक। पहले कोड है, उसी JUMP_ABSOLUTE कथन को बंद कर रहा है।

115   170 LOAD_FAST    3 (q) 
      173 LOAD_CONST    10 (1) 
      176 COMPARE_OP    0 (<) 
      179 JUMP_IF_FALSE   45 (to 227) 
      182 POP_TOP    
      183 LOAD_FAST    11 (z) 
      186 LOAD_CONST    11 (10) 
      189 COMPARE_OP    4 (>) 
      192 JUMP_IF_FALSE   32 (to 227) 
      195 POP_TOP    

116   196 LOAD_CONST    1 (0) 
      199 STORE_FAST    4 (ok) 

117   202 LOAD_FAST    5 (u) 
      205 LOAD_CONST    3 (1) 
      208 BINARY_ADD   
      209 STORE_FAST    5 (u) 

118   212 LOAD_CONST    1 (0) 
      215 STORE_FAST    3 (k) 

119   218 LOAD_CONST    3 (10) 
      221 STORE_FAST    6 (dv) 
      224 JUMP_ABSOLUTE   27 
     >> 227 POP_TOP    

JUMP_FORWARD कहते हैं और JUMP_ABSOLUTE "अगली पंक्ति में जाना" "जबकि पाश की शुरुआत में वापस जाने के" कहते हैं। समस्या यह है कि मुझे नहीं पता कि कोड को दोहराना कैसे है जो उपरोक्त के समान बाइटकोड देगा।

धन्यवाद!

+0

था अपने ' .pyc' पाइथन के उसी संस्करण के साथ बनाया गया है जैसा कि आप अभी उपयोग कर रहे हैं? वह संस्करण कौन सा है? –

+0

मुझे पूरा यकीन है कि इसे पायथन 2.5 के साथ बनाया गया था, वही मैं अभी उपयोग कर रहा हूं।मैंने जादू संख्या की जांच की। – Alex

+0

आपने बताया कि आप जानते हैं कि यह एक लूप नहीं है। लेकिन JUMP_ABSOLUTE 27 इंगित करता है कि कूद आपको कोड में काफी लंबा रास्ता ले रहा है। क्या आपने यह सुनिश्चित करने के लिए कि वास्तव में यह लूप नहीं है, यह देखने के लिए इंडेक्स 27 के साथ ओपोड के रूप में आप वास्तव में वापस क्या देख रहे थे? पूरी तस्वीर देने के लिए अधिक डिस्सेम्बल कोड शामिल करना फायदेमंद हो सकता है, विशेष रूप से ताकि यह देखना संभव हो कि कूद कहाँ जाती है। –

उत्तर

3

मैं चुनौती लिया और आपकी मदद के साथ अपनी स्थिति (या बहुत कुछ इसी तरह) के बाद (बकवास) फ़ंक्शन का उपयोग पुन: पेश करने में सक्षम था: JUMP_ABSOLUTE है कि आप पूछ रहे थे है

>>> def f(): 
... while ok==0: 
...  if q<1 and z>10: 
...  ok=0 
...  u=u+1 
...  k=0 
...  dv=10 
...  elif a<100 and b>10: 
...  ok=1 
... 
>>> dis(f) 
    2   0 SETUP_LOOP    112 (to 115) 
     >> 3 LOAD_FAST    0 (ok) 
       6 LOAD_CONST    1 (0) 
       9 COMPARE_OP    2 (==) 
      12 JUMP_IF_FALSE   98 (to 113) 
      15 POP_TOP 

    3   16 LOAD_GLOBAL    0 (q) 
      19 LOAD_CONST    2 (1) 
      22 COMPARE_OP    0 (<) 
      25 JUMP_IF_FALSE   45 (to 73) 
      28 POP_TOP 
      29 LOAD_GLOBAL    1 (z) 
      32 LOAD_CONST    3 (10) 
      35 COMPARE_OP    4 (>) 
      38 JUMP_IF_FALSE   32 (to 73) 
      41 POP_TOP 

    4   42 LOAD_CONST    1 (0) 
      45 STORE_FAST    0 (ok) 

    5   48 LOAD_FAST    1 (u) 
      51 LOAD_CONST    2 (1) 
      54 BINARY_ADD 
      55 STORE_FAST    1 (u) 

    6   58 LOAD_CONST    1 (0) 
      61 STORE_FAST    2 (k) 

    7   64 LOAD_CONST    3 (10) 
      67 STORE_FAST    3 (dv) 
      70 JUMP_ABSOLUTE   3 
     >> 73 POP_TOP 

    8   74 LOAD_GLOBAL    2 (a) 
      77 LOAD_CONST    4 (100) 
      80 COMPARE_OP    0 (<) 
      83 JUMP_IF_FALSE   23 (to 109) 
      86 POP_TOP 
      87 LOAD_GLOBAL    3 (b) 
      90 LOAD_CONST    3 (10) 
      93 COMPARE_OP    4 (>) 
      96 JUMP_IF_FALSE   10 (to 109) 
      99 POP_TOP 

    9   100 LOAD_CONST    2 (1) 
      103 STORE_FAST    0 (ok) 
      106 JUMP_ABSOLUTE   3 
     >> 109 POP_TOP 
      110 JUMP_ABSOLUTE   3 
     >> 113 POP_TOP 
      114 POP_BLOCK 
     >> 115 LOAD_CONST    0 (None) 
      118 RETURN_VALUE 

लाइन्स 8 और 11 के लिये। LOAD_GLOBAL बनाम LOAD_FAST जैसे थोड़ा अंतर भिन्नता के दायरे के कारण होते हैं।

ध्यान दें कि मुझे इसे पुन: पेश करने के लिए पायथन 2.5 पर स्विच करना पड़ा था। नए संस्करण विभिन्न परिणाम उत्पन्न करते हैं।

continue अपनी स्थिति पर लागू हो प्रतीत नहीं होता है, तो मैं आपको अजगर के स्रोत कोड में कुछ शोध करते हैं और Python/compile.c में ADDOP_JABS के लिए देखो क्या अन्य मामलों एक निरपेक्ष कूद डाला जाता है में पता लगाने के लिए सुझाव देते हैं।

अपने लक्ष्य "बस" इस .pyc डिकंपाइल करने के लिए है, तो आप uncompyle2 जो के रूप में "एक अजगर 2.5, 2.6, 2.7 बाइट-कोड decompiler, अजगर 2.7 में लिखा" में वर्णन की कोशिश करनी चाहिए,

+0

मैंने 'जारी रखने 'के बारे में सोचा नहीं है, यह लगभग समाधान है! समस्या यह है कि यह IF कथन के कारण 'JUMP_FORWARD' को नहीं हटाती है, यह एक पूर्ण कूद जोड़ती है। आपके पास अभी भी लाइन 8 पर 'JUMP_FORWARD' है जो अगली पंक्ति पर इंगित करता है। – Alex

+0

यद्यपि आपने पहले ही उत्तर स्वीकार कर लिया है (धन्यवाद) मैंने जवाब अपडेट किया है और भविष्य के संदर्भ के लिए अपना स्वयं का 'एलिफ' सुझाव डाला है। –

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