अच्छी तरह से आपको ऊपरी छोर में प्रत्येक बिट पर char
के साइन बिट की प्रतिलिपि बनाने की आवश्यकता है। अधिकांश आर्किटेक्चर पर, सीधा एक रजिस्टर और अंकगणितीय-दाएं-इसे 7 तक प्रतिलिपि बनाना होगा। लेकिन एवीआर में केवल shift-by-1 instruction है, इसलिए हम इसे कुशलता से नहीं कर सकते हैं।
सशर्त रूप से 0 या -1 को एक रजिस्टर में प्राप्त करने के लिए एक और चाल subtract-with-borrow0 - C
प्राप्त करने के लिए स्वयं से एक रजिस्टर है। जैसे sbc r25, r25
।
अब 8-बिट संख्या ऋणात्मक होने पर हमें कैरी ध्वज सेट करने का एक तरीका चाहिए, यानी यदि यह> 127 है जब एक हस्ताक्षरित पूर्णांक के रूप में माना जाता है, क्योंकि सी हमेशा चीजों की हस्ताक्षरित व्याख्या के आधार पर सेट की जाती है। एवीआर की एक तुलना-तत्काल निर्देश है, CPI, लेकिन यह केवल आर 16-आर 31 के लिए काम करता है, न कि कम रजिस्टरों के लिए। साथ ही, यह सी फ्लैग को जो हम वास्तव में चाहते हैं उसके विपरीत सेट करता है, इसलिए हमें परिणाम को बदलने के लिए एक और निर्देश का उपयोग करना होगा। तो मुझे लगता है कि हम एक रजिस्टर में एक मूल्य के खिलाफ दूसरी तरह की तुलना कर से बेहतर कर रहे हैं:
; Most efficient way, I think:
sign_extend:
ldi r25, 127 ; can be hoisted out of loops, and any reg is fine.
cp r25, r24 ; C = (r24 < 0)
sbc r25, r25 ; r25 = (r24 < 0) ? -1 : 0
; result in r25:r24
और भी बेहतर, यदि आप एक पाश में ऐसा करने की जरूरत है, तो आप 127 एक अलग रजिस्टर में रख सकते हैं। एक प्रतिबंध है जिस पर प्रयोग किया जाता है रजिस्टर से बचने के लिए
; slightly worse: only works with r16-r31, and worse in loops
sign_extend:
cpi r24, 127 ; C = (r24 < 128U) = ((signed)r24 >= 0)
sbc r25, r25 ; r25 = (r24>=0) ? -1 : 0
com r25 ; ones-complement negation: 0 : -1
या, दूसरी तरह के तुलना करते हैं:
भाकपा के साथ
, आप ऐसा करते हैं होता
मैं AVR के साथ काम किया कभी नहीं किया है , इसलिए मैं इसे निर्देश सेट संदर्भ मैनुअल से बस कर रहा हूं जिसे Google मिला (और अन्य आईएसए के लिए एएसएम का ज्ञान, जैसे कि x86 और एआरएम)। उन दस्तावेज़ों के मुताबिक, उन सभी निर्देश 1 शब्द (2 बाइट्स) हैं, 1 चक्र विलंबता के साथ।
अच्छा अनुदेश दृश्यों को खोजने के लिए हमेशा की तरह एक संकलक पूछने के लिएAVR gcc4.5 -O3
on godbolt करता है:
short sign_extend(signed char a) { return a; }
sign_extend:
mov r18,r24 ;; IDK why gcc uses r18 and r19.
clr r19
sbrc r18,7
com r19
mov r25,r19
ret
तो यह zeros R19, तो SBRC का उपयोग करता है यह वही है gcc4.5 करता है की तुलना में बेहतर है R18 के साइन बिट (बिट 7) के आधार पर सशर्त रूप से लॉजिकल-नहीं (COM) निष्पादित करने के लिए।
मुझे यकीन नहीं है कि अतिरिक्त एमओवी क्या हैं। मुझे यह भी यकीन नहीं है कि यह सभी बिट्स को इनपुट-निर्भरता के साथ सेट करने के बजाय शून्य को क्यों बदलता है। (उदाहरण के लिए ldi r19, $FF
, या SBR alias for it। यदि आउट ऑफ़ ऑर्डर-निष्पादन एवीआर कभी अस्तित्व में है, तो यह अधिक कुशल होगा।: पी
मुझे यकीन नहीं है कि एमओवी निर्देश क्या हैं। एसबीआरसी गैर- विनाशकारी।AFAICT तो, एक वैध कार्यान्वयन
sign_extend:
clr r25
sbrc r24,7
ldi r25, $FF
ret
होगा यह अभी भी CP/SBC से भी बदतर है, क्योंकि SBRC 2 चक्र लेता है, तो छोड़ लिया जाता है।
मुझे लगता है कि आर 25 के पुराने मूल्य पर एसबीसी की "झूठी निर्भरता" एवीआर पर एक बात नहीं है। आउट-ऑफ-ऑर्डर x86 सीपीयू पर, केवल एएमडी sbb eax, eax
को ईएक्स के पुराने मूल्य से स्वतंत्र होने के रूप में पहचानता है, और केवल झंडे के आधार पर। इंटेल सीपीयू बस इसे सामान्य रूप से चलाते हैं। तो गैर एएमडी CPUs पर (वे xor eax,eax
स्वतंत्र रूप में, और it's the standard zeroing-idiom for x86 की तरह निर्देश पहचान कर सकते हैं।)
, अगर पिछले कोड कि EAX लिखा एक लोड है कि कैश में याद किया, या कुछ और उच्च विलंबता के साथ वैसा ही किया, sbb eax, eax
ध्वज तैयार होने के बावजूद निष्पादित नहीं हो सका (यानी एक स्वतंत्र निर्भरता श्रृंखला से)। लेकिन एएमडी सीपीयू पर, यह ईएक्स के लिए एक नई निर्भरता श्रृंखला शुरू करेगा।
वैसे भी, मुझे लगता है कि एवीआर एक साधारण सरल क्रम में पाइपलाइन डिजाइन है, इसलिए पुराने पंजीकरण के लिए एक प्रदर्शन भूमि-मेरा होने का कोई तरीका नहीं है जब तक कि कोड (उदाहरण के लिए) इसमें कैश-मिस लोड नहीं होता परिणाम का कभी भी उपयोग नहीं किया। (यहां तक कि इन-आदेश पाइपलाइनों जब तक कुछ परिणाम का उपयोग करता है उच्च विलंबता के संचालन के लिए प्रतीक्षा करने की आवश्यकता नहीं है।)
पर हस्ताक्षर किए संख्या के लिए कौन सा प्रारूप शिक्षक परोक्ष संभालने रहा है? दो का अनुपूरण? –
@MargaretBloom: AVR के साइन-ध्वज की तरह यह बिट्स की 2 के पूरक व्याख्या के आधार पर सेट है लगता है, इसलिए मुझे लगता है कि कह बिना चला जाता है लगता है। इसके अलावा [एनईजी निर्देश] (http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_NEG.html) 2 की पूरक अस्वीकृति करता है। –
@ पीटरकॉर्डस एह, शायद या शायद नहीं। पाठ्यक्रम के दो पूरक मानना उचित है लेकिन अन्य हस्ताक्षरित प्रतिनिधित्वों को लागू करने के बारे में एक अभ्यास हो सकता है (वास्तव में आईएसए से समर्थन की कमी के कारण)। मैंने हालांकि दो पूरक भी माना। –