समस्या यह है कि एक सी समारोह के अंदर मेरे पास एक इनलाइन असेंबली है। कुछ की तरहइनलाइन असेंबली के लिए निरंतर पूल बनाने का सही तरीका क्या है?
ldr r7, =0xdeadbeef
svc 0
तो एक शाब्दिक पूल स्पष्ट रूप से (यदि यह मामला है) नहीं बनाया गया था, कोडांतरक अनुवाद इकाई के अंत में एक बनाता है। आमतौर पर यह ठीक है, लेकिन अगर अनुवाद इकाई वास्तव में बड़ी हो जाती है, तो यह काम नहीं करती है, क्योंकि शाब्दिक पूल एलडीआर निर्देश से बहुत दूर है।
तो, मुझे आश्चर्य है कि समस्या को संभालने का सबसे अच्छा तरीका क्या है। सबसे स्पष्ट रास्ता इनलाइन विधानसभा के अंदर स्वयं एक शाब्दिक पूल बनाने के लिए है:
ldr r7, =0xdeadbeef
svc 0
b 1f
.ltorg
1:
या
ldr r7, 1f
svc 0
b 2f
1:
.word 0xdeadbeef
2:
दुर्भाग्य से, यह अनावश्यक शाखा अनुदेश की वजह से एक से इनकी कोड होता है। मैं उम्मीद नहीं करता कि असेंबलर फ़ंक्शन के अंदर निरंतर पूल के लिए उचित स्थान ढूंढने के लिए पर्याप्त चालाक हो। मैं क्या करना चाहता हूं फ़ंक्शन के अंत में एक निरंतर पूल बनाएं। समारोह के अंत में एक शाब्दिक पूल बनाने के लिए संकलक (gcc) को बताने का कोई तरीका है?
पीएस मैं लगातार पूल के बजाय movw/movt
जोड़ी का उपयोग कर समाप्त हुआ। हालांकि, सबसे पहले, movw/movt समाधान शाब्दिक पूल की तुलना में थोड़ा कम पोर्टेबल है और दूसरी बात है, मुझे आश्चर्य है कि इनलाइन असेंबली दोनों निरंतर और कुशलता से निरंतर पूल का उपयोग करना संभव है या नहीं।
अद्यतन:तो, क्या सबसे अच्छा तरीका है समस्या को संभालने के लिए है?
फ़ंक्शन के बाद एक स्थिर पूल बनाने के लिए टूलचेन को मजबूर करने के लिए कोई अलग कोड अनुभाग में फ़ंक्शन डाल सकता है। यह काम करता है क्योंकि एक अनुवाद इकाई असेंबलर के अंत में प्रत्येक अनुभाग के लिए अलग निरंतर पूल उत्पन्न करता है।
हालांकि, वास्तव में सर्वोत्तम तरीका इनलाइन असेंबली में रजिस्टरों में स्थिरांक लोड करने से बचने के लिए है। संकलक को ऐसा करने देना बेहतर है। मेरे मामले में मैं अंत में
register int var asm("r7") = 0xdeadbeef;
asm volatile("svc 0\n" :: "r" (var));
संभवतः बाधाओं का उपयोग करना सही तरीका है लेकिन यह जादू की तरह है। https://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html – auselen