2012-01-28 13 views
5

क्या कोई मुझे एआरएम बिट-शिफ्ट की व्याख्या कर सकता है जैसे कि मैं पांच वर्ष का हूं? मुझे किसी भी चीज की बहुत कम समझ है जिसमें गैर-दशमलव संख्या प्रणाली शामिल है ताकि बिट बदलावों और बिटवाई ऑपरेटरों की अवधारणाओं को समझना मेरे लिए मुश्किल हो।क्या कोई मुझे एआरएम bitwise संचालन समझा सकता है?

निम्नलिखित में से प्रत्येक मामले क्या करेगा और क्यों (R3 में क्या होगा और बिट स्तर पर दृश्यों के पीछे क्या होता है)?

/** LSL **/ 
mov r0, #1 
mov r3, r0, LSL#10 

/** LSR **/ 
mov r0, #1 
mov r3, r0, LSR#10 

/** ORR **/ 
mov r0, #1 
mov r1, #4 
orr r3, r1, r0 

/** AND **/ 
mov r0, #1 
mov r1, #4 
and r3, r1, r0 

/** BIC **/ 
mov r0, #1 
mov r1, #4 
bic r3, r1, r0 

पी एस। सी बिटवाई ऑपरेटरों के संदर्भ में इसे समझाएं। मुझे नहीं पता कि वे क्या करते हैं (>>, <<, |, & वाले)।

उत्तर

15

सत्य टेबल, दो आदानों, छोड़ दिया और एक उत्पादन पर दो नंबर, दायीं ओर की संख्या:

या

a b c  
0 0 0 
0 1 1 
1 0 1 
1 1 1 

छोड़ दो आदानों ए और बी चार संभव संयोजनों का प्रतिनिधित्व इनपुट के, सूची में कोई भी कम नहीं है।

सत्य का मतलब 1 और झूठा मतलब 0 पर विचार करें। और शब्द या इस मामले में इसका मतलब है कि यदि कोई OR बी सत्य है तो सी सत्य है। और जैसा कि आप तालिका में देखते हैं, क्षैतिज रूप से यदि कोई या बी सत्य है तो सी सत्य है।

और

a b c 
0 0 0 
0 1 0 
1 0 0 
1 1 1 

और वे इसका मतलब है दोनों सच ए और बी हैं अगर दोनों सच तो ग सच है की है। केवल एक ही मामला है जहां यह ऊपर मौजूद है।

अब दो बाइट 0x12 और 0x34 लें जो दशमलव में 18 और 52 हैं, लेकिन हम वास्तव में दशमलव के बारे में बहुत अधिक परवाह नहीं करते हैं। हम बाइनरी 0x12 0b00010010 और 0x34 0b00110100 के बारे में परवाह करते हैं। असेंबली भाषा में AND और OR और XOR जैसे bitwise ऑपरेटरों का मतलब है कि आप प्रत्येक ऑपरेंड से एक बिट लेते हैं और इससे परिणाम एक ही स्थान पर मिलता है। यह ऐसा नहीं है जहां आपके पास इस तरह की चीजें हैं जो ब्लाह के बराबर होती है।

तो हम बिट्स

0b00010010 0x12 
0b00110100 0x34 

तो अपने सिर sidways झुकाव आप की तरह एक टैको अपने बाएं हाथ में आयोजित से बाहर एक निवाला ले सकते हैं और इसके बाद के संस्करण सच्चाई तालिका कल्पना करने के लिए जा रहे हैं लाइन अप। यदि हम दाईं ओर दो बिट्स देखते हैं तो वे 0 और 0 हैं, अगले दो बिट्स 1 और 0 हैं और इसी तरह।तो अगर हम एक या आपरेशन करना चाहता था, शासन करता है, तो या तो एक या बी सच है तो सी, परिणाम,

0b00010010 
    0b00110100 
OR ========== 
    0b00110110 

हेड सही करने के लिए झुका, कम से कम महत्वपूर्ण बिट (लोगों में थोड़ा सच है है संख्या में कॉलम) 0 या 0 = 0, न तो कोई सेट है। अगला कॉलम (जुड़वां कॉलम) 1 या 0 = 1 कम से कम एक सत्य है। और इतने तो

0x12 या 0x34 = हाथ विधानसभा में 0x36

पर

mov r0,#0x12 
mov r1,#0x34 
orr r2,r0,r1 
या ऑपरेशन r2 मूल्य 0x36 पकड़ के बाद

होंगे।

अब की सुविधा देता है और उसके अंकों को

0b00010010 
    0b00110100 
AND ========== 
    0b00010000 

हमारे सच्चाई तालिका को याद और शासन दोनों ए और बी सही होना जरूरी (क 1) हम सही, 0 करने के लिए हमारे सिर झुकाव और 0 0, दोनों है सच नहीं हैं और निरीक्षण के द्वारा केवल एक कॉलम में 1, 16s कॉलम के साथ दोनों इनपुट होते हैं। यह हमें 0x12 और 0x34 = 0x10

साथ छोड़ देता है बांह विधानसभा में हो सकता है कि

mov r0,#0x12 
mov r1,#0x34 
and r2,r0,r1 

अब हम बीआईसी अनुदेश को मिलता है। जो बिटवाई स्पष्ट के लिए खड़ा है, जो उम्मीद है कि थोड़ा सा समझ में आ जाएगा। हाथ पर बाइक बी के साथ एक एंडेड है। नहीं एक और सच तालिका है, लेकिन केवल एक ही इनपुट और आउटपुट

नहीं

a c 
0 1 
1 0 

केवल एक ही इनपुट के साथ हम केवल दो विकल्प 0 और 1 है, 1 सच है 0 गलत है। इसका मतलब यह नहीं है कि यदि कोई नहीं तो सत्य है। जब कोई सत्य नहीं है, तो सत्य है, जब एक सत्य सी सच नहीं है। असल में यह बदल जाता है।

क्या बीआईसी करता है दो आदानों ए और बी है, आपरेशन (नहीं ख) ग = एक है और इसलिए है कि के लिए सच तालिका होगा:

एक और (नहीं ख)

a b c 
0 1 0 
0 0 0 
1 1 0 
1 0 1 

मैंने और सत्य तालिका के साथ शुरू किया, फिर बी बिट्स को नोट किया, जहां बी 0 और सत्य तालिका में 0 था, मैंने इसे 1 बनाया जहां बी बी और सत्य तालिका में 1 था। मैंने इसे 0

बनाया

तो 0x12 और 0x34 पर बाइक ऑपरेशन

है
0b00010010 
    0b00110100 
BIC ========== 
    0b00000010 

इसे थोड़ा स्पष्ट क्यों कहा जाता है? समझना जो इसे उपयोग करना अधिक आसान बनाता है। यदि आप सच तालिका देखते हैं और पहले और दूसरे इनपुट के बारे में सोचते हैं। जहां दूसरा, बी, इनपुट 1 है, आउटपुट 0 है। जहां दूसरा इनपुट, बी, 0 है, आउटपुट स्वयं ही अनमोडिफाइड है। तो वह सत्य तालिका या ऑपरेशन क्या कर रहा है यह कह रहा है कि कहीं भी बी को सेट किया गया है या उन बिट्स को शून्य में शून्य किया गया है। इसलिए यदि मेरे पास 0x1234 संख्या है और मैं निचले 8 बिट्स को शून्य करना चाहता हूं, तो मैं बीआईसी 0x00FF के साथ चाहता हूं। और आपका अगला सवाल यह है कि क्यों नहीं और 0xFF00 के साथ? (और सत्य तालिका का विश्लेषण करें और देखें कि जहां भी बी 1 है, आप एक मान रखते हैं, और जहां भी बी 0 है, आप आउटपुट शून्य करते हैं)। एआरएम 32 बिट रजिस्टरों का उपयोग करता है, और एक निश्चित 32 बिट निर्देश सेट, कम से कम परंपरागत रूप से।तत्काल निर्देश

mov r0,#0x12 

हाथ में 8 गैर शून्य बिट्स तक ही सीमित हैं संख्या के भीतर कहीं भी स्थानांतरित कर दिया, कुछ ही देर में स्थानांतरण करने के लिए मिल जाएगा। तो अगर मैं मूल्य 0x12345678 था और कम 8 बिट मैं कर सकता इस

; assume r0 already has 0x12345678 
bic r0,r0,#0xFF 

या

; assume r0 already has 0x12345678 
mov r1,#0xFF000000 
orr r1,r1,#0x00FF0000 
orr r1,r1,#0x0000FF00 
;r1 now contains the value 0xFFFFFF00 
and r0,r0,r1 

या

; assume r0 already contains 0x12345678 
ldr r1,my_byte_mask 
and r0,r0,r1 
my_byte_mask: .word 0xFFFFFF00 

जो भयानक नहीं है, की तुलना में को शून्य करना चाहता था एक चाल और दो ऑरर्स का उपयोग करके, लेकिन अभी भी बाइक समाधान की तुलना में अधिक घड़ी चक्र जलता है क्योंकि आप राम से my_byte_mask पढ़ने के अतिरिक्त मेमोरी चक्र को जलाते हैं, जिसमें कुछ समय लग सकता है।

या

; assume r0 already contains 0x12345678 
mvn r1,#0xFF 
and r0,r0,r1 

यह पिछले एक एक बुरा समझौता नहीं किया जा रहा। ध्यान दें कि हाथ प्रलेखन में एमवीएन बिटवाई तत्काल नहीं है, इसका मतलब है आरएक्स = नहीं (तत्काल)। तत्काल यहां 0xFF है। नहीं (0xFF) का अर्थ है सभी बिट्स को उलटा करना, यह 32 बिट रजिस्टर है जिसके लिए हम जा रहे हैं, इसका मतलब है कि 0xFFFFFF00 नॉट (0xFF) का नतीजा है और यही वह करने से पहले रजिस्टर आर 1 प्राप्त होता है।

तो यही वजह है कि बीआईसी एआरएम अनुदेश सेट में एक जगह है, क्योंकि कभी कभी यह कम निर्देश या घड़ी चक्र लेता है नकाब (मुखौटा = और कुछ बिट्स शून्य बनाने के लिए इस्तेमाल) के बजाय बीआईसी अनुदेश का उपयोग कर और अनुदेश।

मैंने मास्क शब्द को अकेले छोड़कर संख्या शून्य में बिट्स बनाने के लिए एक अवधारणा के रूप में इस्तेमाल किया। ऑरिंग को अकेले दूसरों को छोड़कर किसी एक में बिट्स बनाने के बारे में सोचा जा सकता है, यदि आप या सत्य तालिका को देखते हैं तो बी 1 है तो सी 1 है। तो 0x12345678 या 0x000000FF परिणाम 0x123456FF में दूसरे में बिट्स ऑपरेंड सेट हैं। हां यह भी सच है कि किसी भी समय या सत्य तालिका में सेट किया गया है, तो आउटपुट सेट किया गया है, लेकिन जब आप इन बिटवाई ऑपरेशंस का उपयोग करते हैं तो आपके पास एक ऑपरेंड होता है जिसे आप कुछ करना चाहते हैं, बिट्स की एक निश्चित संख्या निर्धारित करें बाकी को संशोधित किए बिना या बाकी को संशोधित किए बिना बिट्स की एक निश्चित संख्या शून्य पर सेट करें या आप बिट्स की एक निश्चित संख्या को छोड़कर सभी बिट्स को शून्य करना चाहते हैं। जब इस तरह इस्तेमाल किया जाता है तो आपके पास एक ऑपरेंड आ रहा है जिसमें आप काम करना चाहते हैं और आप जो समग्र प्रभाव चाहते हैं उसके आधार पर दूसरा ऑपरेंड बनाते हैं, उदाहरण के लिए सी में अगर हम केवल निचले बाइट रखना चाहते हैं तो हम कर सकते हैं में, एक पैरामीटर बाहर समारोह एक एक पैरामीटर है:

unsigned int keep_lower_byte (unsigned int a) 
{ 
    return(a&(~0xFF)); 
} 

~ साधन नहीं तो ~ 0xFF, 32 बिट संख्या के लिए 0xFFFFFF00 का मतलब तो & का अर्थ है और, इसलिए हम एक & 0xFFFFFF00 लौट आते हैं। एकमात्र असली ऑपरेंड आ रहा था और हमने दूसरे ऑपरेशन के आधार पर आविष्कार किया था जिसे हम करना चाहते थे ... अधिकांश बिटवाई ऑपरेशंस आप निर्देशों में ऑपरेंड को स्वैप कर सकते हैं और सब ठीक हो जाता है, एआरएम की बाइक जैसे निर्देश, हालांकि ऑपरेंड हैं एक निश्चित क्रम में, बस एक घटाने की तरह आपको ऑपरेंड के सही क्रम का उपयोग करना होगा।

स्थानांतरित करना ... दो प्रकार, तार्किक और अंकगणित हैं। लॉजिकल सबसे आसान है और जब आप सी < सी

0x12 से शुरू करें जो 0b00010010 है, तो आप क्या प्राप्त करते हैं।शिफ्टिंग बाएं (0x12 < < 3) के लिए तीन स्थानों का मतलब है कि

00010010 < our original number 0x12 
0010010x < shift left one bit location 
010010xx < shift left another bit location 
10010xxx < shift left a third bit location 

क्या बिट्स प्राप्त खाली स्थानों के लिए "में स्थानांतरित कर दिया", ऊपर x'es, आपरेशन के आधार पर भिन्न।

00010010 < our original number 0x12 
00100100 < shift left one bit location 
01001000 < shift left another bit location 
10010000 < shift left a third bit location 

लेकिन कभी कभी (आमतौर पर हर अनुदेश सेट एक बदलाव के साथ ही एक घुमाने का समर्थन करता है) वहाँ शिफ्ट करने के लिए अन्य तरीके हैं और मतभेदों को क्या आप में बदलाव थोड़ी क्या करना है: सी प्रोग्रामिंग के लिए यह हमेशा शून्य है खाली जगह, और कभी-कभी जिस चीज को आप अंत से बाहर ले जाते हैं वह हमेशा गायब नहीं होता है कभी-कभी आप उसे एक विशेष बिट धारक स्थान में सहेजते हैं।

कुछ निर्देश सेटों में केवल एक ही बिट शिफ्ट होता है जिसका अर्थ है कि आप प्रत्येक प्रोग्राम के लिए केवल एक बिट को स्थानांतरित कर सकते हैं, इसलिए ऊपर एक ही समय में 3 निर्देश होंगे, एक बिट। हाथ की तरह अन्य निर्देश सेट, आपको एक ही निर्देश प्राप्त करने की अनुमति देते हैं और आप निर्देश में निर्दिष्ट करते हैं कि आप उस दिशा में कितनी बिट्स को स्थानांतरित करना चाहते हैं। इसलिए एक पारी तीन

mov r0,#0x12 
mov r3,r0,lsl#3 ; shift the contents of r0 3 bits to the left and store in r3 

क्या आप में LSR और ASR, तार्किक पारी सही और गणित पारी सही के बीच का प्रदर्शन किया है बदलाव की यह अलग-अलग छोड़ दिया (आप कोई एएसएल है कि वहाँ देखेंगे, गणित पारी छोड़ दिया है कि बनाता है क्योंकि कोई मतलब नहीं, कुछ असेंबलर आपको एएसएल निर्देश का उपयोग करने की अनुमति देंगे लेकिन इसे एलएसएल के रूप में एन्कोड करेंगे)।

एक तार्किक पारी सही:

00010010 - our original number 0x12 
x0001001 - shifted right one bit 
xx000100 - shifted right another bit 
xxx00010 - shifted right another bit 

सी के साथ के रूप में वहाँ एक संस्करण है कि शून्य में बदलाव है, जो तार्किक पारी सही शून्य में स्थानांतरण है,

00010010 - our original number 0x12 
00001001 - shifted right one bit 
00000100 - shifted right another bit 
00000010 - shifted right another bit 

गणित बदलाव सही साधन की रक्षा "साइन बिट" साइन बिट क्या है? जो दो पूरक पूरक संख्याओं में आता है जिन्हें आपको सीखने की आवश्यकता होती है यदि आपने नहीं किया है। असल में यदि आप बिट पैटर्न/मान को दोहरे पूरक संख्या मानते हैं तो सबसे महत्वपूर्ण बिट, बाईं ओर वाला, साइन बिट है। यदि यह 0 है तो संख्या सकारात्मक है और 1 संख्या ऋणात्मक है। आपने देखा होगा कि एक बिट द्वारा छोड़ा गया शिफ्ट 2 से गुणा करने जैसा ही है और एक शिफ्ट दाएं 2. 0x12 >> 1 = 0x9, 18 >> 1 = 9 से विभाजित होने जैसा ही है, लेकिन अगर हम शिफ्ट करना चाहते हैं तो क्या होगा दाएं से एक शून्य 2, बाइट्स या 0b11111110 का उपयोग करके शून्य से दो 0xFE है। सी शैली तार्किक शिफ्ट दाएं 0xFE >> 1 = 0x7F, या दशमलव -2 >> 1 = 0x127 का उपयोग कर। हम एक भी आपरेशन में हल कर सकते हैं नहीं है कि सी में, दुर्भाग्य से, लेकिन विधानसभा में हम अंकगणितीय पारी का उपयोग कर सकते हैं, यह मानते हुए अपने अनुदेश सेट है, जो हाथ

गणित पारी सही

s1100100 - our starting value s is the sign bit whatever that is 0 or 1 
ss110010 - one shift right 
sss11001 - another shift right 
ssss1100 - another shift right 

तो अगर करता है जब हम शुरू कर दिया संकेत बिट एक 0 था, अगर संख्या 01,100,100 तो

01100100 - our starting value 
00110010 - one shift right 
00011001 - another shift right 
00001100 - another shift right 

था, लेकिन अगर उस पर हस्ताक्षर बिट एक एक

11100100 - our starting value 
11110010 - one shift right 
11111001 - another shift right 
11111100 - another shift right 
किया गया था

और हम 0xFE हल कर सकते हैं सही स्थानांतरित कर दिया:

11111110 - 0xFE a minus 2 in twos complement for a byte 
11111111 - shifted right one 

तो छद्म कोड 0xFE ASR 1 = 0xFF, -2 ASR में 1 = -1।-2 द्वारा विभाजित 2 = -1

आखिरी चीज जो आपको स्वयं को पढ़ने की जरूरत है उसे घूर्णन के साथ करना है और/या अंत में स्थानांतरित होने वाली बिट के साथ क्या होता है। एक शिफ्ट दाहिने तरफ एलएसबीटी को "अंत से दूर" स्थानांतरित किया जाता है जैसे कि ब्लॉक एक टेबल के ढीले होते हैं और जो गिरता है वह सिर्फ "बिट बाल्टी" (ईथर, स्वर्ग या नरक, इन स्थानों में से एक में जा सकता है जहां बिट्स जब वे इस दुनिया से गायब हो जाते हैं तो मर जाते हैं)। लेकिन कुछ निर्देश सेटों में कुछ निर्देश उस बिट को स्थानांतरित कर लेते हैं और इसे कैरी फ्लैग में डालते हैं (जोड़ और घटाव पर पढ़ते हैं), क्योंकि यह आवश्यक रूप से एक वाहक नहीं है बल्कि क्योंकि अलू और कैरी बिट में स्थिति बिट्स हैं एक ऐसा है जो थोड़े समझ में आता है। अब क्या घुमावदार है, मान लीजिए कि आपके पास 8 बिट प्रोसेसर था और आप एक बिट घुमाएंगे, कैरी बिट में अंत भूमि से थोड़ा सा गिर रहा है, और दूसरी तरफ थोड़ा स्थानांतरण करना कैरेट बिट में था ऑपरेशन से पहले। असल में यह संगीत कुर्सियां ​​है, बिट्स कुर्सियों के चारों ओर घूम रहे हैं, जिसमें एक व्यक्ति खड़ा रहता है, खड़े व्यक्ति को ले जाने वाला व्यक्ति होता है, कुर्सियों में लोग रजिस्टर में बिट्स होते हैं। यह बिल्कुल उपयोगी क्यों है? आइए कहें कि हमारे पास 8 बिट प्रोसेसर था जैसे एटमेल एवीआर उदाहरण के लिए, लेकिन 64 बिट शिफ्ट करना चाहता था। 64 बिट्स 8, 8 बिट, रजिस्टर्स लेते हैं, कहते हैं कि मेरे पास 8 रजिस्टरों में मेरा 64 बिट नंबर है और मैं 64 बिट शिफ्ट को एक बिट छोड़ना चाहता हूं। मैं कम से कम महत्वपूर्ण बाइट से शुरू करूंगा और एक एलएसएल करता हूं जो शून्य में बदलाव करता है लेकिन बिट स्थानांतरण बाहर ले जाने के लिए जाता है। तो अगले सबसे महत्वपूर्ण बाइट मैं एक रोल करता हूं, बाएं एक बिट घुमाता है, थोड़ा सा आ रहा है थोड़ा बाइट से बाहर जा रहा है और थोड़ी सी बाहर ले जाने के लिए जाता है। मैं अन्य बाइट्स के लिए ROL अनुदेश दोहराए जाते हैं, एक 16 बिट पारी को देखकर:

00100010 z0001000 - our original number 
00100010 z 0001000 - lsl the least significant byte, the ms bit z is in carry 
0100010z 00010000 - rotate left the most significant byte pulling the z bit from carry 

00100010z0001000 - if it had been a 16 bit register 
0100010z00010000 - a logical shift left on a 16 bit with a zero coming in on the left 

है कि क्या घूमता है के लिए कर रहे हैं और यही वजह है कि विधानसभा के मैनुअल में बताने के लिए क्या झंडे संशोधित कर रहे हैं जब आप एक प्रदर्शन परेशान तार्किक ऑपरेशन।

+0

वाह, आपके उत्तर ने मुझे प्रभावित किया! –

+0

यह वास्तव में एक अच्छा जवाब है! क्या हम इसे सहेजने के लिए व्यवस्थापक से पूछ सकते हैं? – 71GA

+0

@old_timer क्या आपको शायद पता चलेगा कि मुझे अपने बीआईसी सिंटैक्स का उपयोग करते समय थंब के संकलन के दौरान बेकार आर 0, आर 0, # 0x3 क्यों प्राप्त किया गया है? क्या यह अभी भी 2007 से एक बग है? https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34436 – 71GA

3

मैं पहली बार एक कर देंगे और उसके बाद हो सकता है आप कोशिश करते हैं और एक समान दृष्टिकोण का उपयोग कर बाकी काम कर सकते हैं:

/** LSL **/ 
mov r0, #1   ; r0 = 0000 0000 0000 0000 0000 0000 0000 0001 
mov r3, r0, LSL#10 ; r3 = r0 logically shifted left by 10 bit positions 
          = 0000 0000 0000 0000 0000 0100 0000 0000 
                ^  ^
                 +<<<<<<<<<<<+ 
                shift left 10 bits 

नोट तथापि है कि अगर आप अभी तक इस तरह के या के रूप में बूलियन संचालन समझ में नहीं आता (|), और (&), आदि, तो आपको संबंधित एआरएम निर्देशों (ORR, AND, आदि) को समझने में कठिनाई होगी।