2009-06-11 8 views
9

मुझे हाल ही में असेंबली स्तर पर एक कार्यक्रम डीबग करने की आवश्यकता है। मेरे पास बहुत सारे असेंबलर अनुभव नहीं हैं, इसलिए मैंने सोचा कि मैं कुछ साधारण सी प्रोग्राम और एकल-चरण लिखूंगा ताकि भाषा के बारे में महसूस हो सके, इससे पहले कि मैं अन्य लोगों के कोड को डीबग करना शुरू कर दूं। हालांकि, मैं वास्तव में नहीं मिलता है क्या इन दो पंक्तियों से बना जीसीसी (-ggdb -O0 साथ संकलित):असेंबली का यह टुकड़ा कैसे काम करता है?

items[tail] = i; 
tail = (tail+1) % MAX_SIZE; 

जहां MAX_SIZE 5 होने के लिए #defined है और मैं एक स्थानीय चर (0x8 में जमा हो जाती है (% ईबीपी), मुझे लगता है)। gdb के अनुसार, इस हो जाता है:

0x08048394 <queue+17>: mov 0x8049634,%edx 
0x0804839a <queue+23>: mov 0x8(%ebp),%eax 
0x0804839d <queue+26>: mov %eax,0x804963c(,%edx,4) 
0x080483a4 <queue+33>: mov 0x8049634,%eax 
0x080483a9 <queue+38>: lea 0x1(%eax),%ecx 
0x080483ac <queue+41>: movl $0x66666667,-0xc(%ebp) 
0x080483b3 <queue+48>: mov -0xc(%ebp),%eax 
0x080483b6 <queue+51>: imul %ecx 
0x080483b8 <queue+53>: sar %edx 
0x080483ba <queue+55>: mov %ecx,%eax 
0x080483bc <queue+57>: sar $0x1f,%eax 
0x080483bf <queue+60>: mov %edx,%ebx 
0x080483c1 <queue+62>: sub %eax,%ebx 
0x080483c3 <queue+64>: mov %ebx,-0x8(%ebp) 
0x080483c6 <queue+67>: mov -0x8(%ebp),%eax 
0x080483c9 <queue+70>: shl $0x2,%eax 
0x080483cc <queue+73>: add -0x8(%ebp),%eax 
0x080483cf <queue+76>: mov %ecx,%edx 
0x080483d1 <queue+78>: sub %eax,%edx 
0x080483d3 <queue+80>: mov %edx,-0x8(%ebp) 
0x080483d6 <queue+83>: mov -0x8(%ebp),%ebx 
0x080483d9 <queue+86>: mov %ebx,0x804963 

के बाद से 0x804963c आइटम का पता है, मैं कैसे सी कोड की पहली पंक्ति से काम करता है देख सकते हैं। इसके अलावा, 0x8049634 पूंछ का पता है, इसलिए मुझे लगता है कि कतार + 33 और कतार + 38% ecx = tail + 1 के बराबर हैं ... लेकिन मुझे नहीं पता कि बाद में क्या हो रहा है। किसने सोचा होगा कि एक साधारण मॉड्यूलो यह जटिल हो सकता है?

उत्तर

14

यह एक अधिक महंगा विभाजन निर्देश करने से बचने का एक तरीका है। पहली बार मुझे सामना करने के बाद भी मैं काफी स्टंप था। मजेदार बात यह है कि इस चाल के लिए उपयोग की जाने वाली जादू संख्याओं की खोज (इस मामले में 0x66666667) अक्सर इस चाल को समझाते हुए परिणाम देती है। (मुझे विश्वास है कि उस समय मुझे एकमात्र ठोस चीज थी जिस पर मुझे जाना था क्योंकि) मेरे पास स्रोत नहीं थे।)

एक त्वरित खोज ने मुझे यह ब्लॉग पोस्ट दिया: http://blog.dkbza.org/2007/09/reverse-engineering-compiler-produced.html इसमें नीचे कुछ उपयोगी लिंक हैं (इस चाल पर एक पेपर के अप्रत्यक्ष लिंक सहित)।

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