2012-01-21 31 views
7

से एआरएम असेंबली को कॉल करना मैं जीसीसी के साथ एआरएम में कुछ नंगे धातु प्रोग्रामिंग करने और क्यूईएमयू पर परीक्षण करने की कोशिश कर रहा हूं। जब भी मैं सी से एआरएम लेबल में कॉल करता हूं, तो मेरा प्रोग्राम लटकता है। मेरे पास कोड का एक साधारण उदाहरण है जो https://gist.github.com/1654392 पर समस्या दिखाता है - जब मैं उस कोड में सक्रिय() को कॉल करता हूं, तो यह लटकता है।सी, जीसीसी (नंगे धातु)

मैंने objdump के साथ देखा है कि जब मैं असेंबली से सी कोड (_start से) के लिए एक ब्लू करता हूं तो यह एक छोटा रैपर उत्पन्न करता है जो थंब निर्देशों पर स्विच करता है। ऐसा लगता है कि सी कोड सभी अंगूठे निर्देशों में उत्पन्न हो रहा है, लेकिन मेरी सभी असेंबली एआरएम (32-बिट) निर्देशों में उत्पन्न की जा रही है। मैं यह नहीं समझ सकता कि यह क्यों है या इसे कैसे ठीक किया जाए।

+0

जहां से इस संकलक है? –

+0

kernel.o :(ARM.exidx + 0x0):। '__aeabi_unwind_cpp_pr1 'के लिए अपरिभाषित संदर्भ मेकअप: *** [kernel.elf] त्रुटि 1 –

+0

आप एक हाथ linux आवेदन का निर्माण करने की कोशिश कर रहे हैं? या एक एम्बेडेड (कोई ऑपरेटिंग सिस्टम) आवेदन? यदि एक लिनक्स एप्लिकेशन है तो आपको स्टार्टअप कोड की आवश्यकता नहीं है टूललैन को आपके लिए यह सब करना चाहिए, आप मुख्य प्रविष्टि के बारे में चिंता करते हैं()। –

उत्तर

5

सी में परिभाषित एक THUMB मोड फ़ंक्शन से असेंबली में परिभाषित एआरएम मोड फ़ंक्शन को कॉल करने के लिए, आपको एक समारोह के रूप में असेंबली में एक प्रतीक परिभाषित करने की आवश्यकता है, और उपकरण (लिनारो जीसीसी) blx निर्देश का उत्पादन करेगा bl

उदाहरण:

@ Here, we suppose that this part of code is inside of .code 32 

.type fn, %function 

fn: 
    mov pc, lr 
+0

के लिए असेंबली कोड की आवश्यकता है धन्यवाद!यह पूरी तरह से काम करता प्रतीत होता है, और मुझे लाइब्रेरी कोड में लिंक करने की अनुमति देता है! – singpolyma

3

http://github.com/dwelch67/yagbat qemu निर्देशिका देखें।

यहाँ

start_vector: 
    mov sp,#0x20000 
    ;@ call an arm function from arm 
    bl notmain 

    ;@ call a thumb function frm arm 
    ldr r0,=0xAABBAABB 
    bl hexstring_trampoline 

    ;@ call a thumb function frm arm 
    ldr r0,=0x12341234 
    ldr r1,hexstring_addr 
    mov lr,pc 
    bx r1 

    ;@ call a thumb function frm arm 
    ldr r0,=0x12312344 
    bl hexstring_trampoline 

hang: 
    b hang 

hexstring_trampoline: 
    ldr r1,hexstring_addr 
    bx r1 

hexstring_addr: .word hexstring 

आप अनुदेश सेट संदर्भ को देखें, तो आपको लगता है कि आप हाथ और अंगूठे राज्यों के बीच स्विच करने BX या BLX उपयोग करने की आवश्यकता देखेंगे हाथ से हाथ या अंगूठे बुला के उदाहरण के एक जोड़े हैं । बीएलएक्स बीएक्स के रूप में व्यापक रूप से समर्थित नहीं है।

परिभाषा से कार्यक्रम काउंटर, पीसी निर्देश के निष्पादन के दौरान आगे दो निर्देश हैं। हाथ 8 बाइट्स के लिए, 4 बाइट्स के अंगूठे के लिए। या तो मामला दो निर्देश। एक ब्लू अनुकरण करने के लिए जो राज्य को बदलने के लिए उपयोग नहीं किया जा सकता है, आपको लिंक पते को रिटर्न पते के साथ लोड करना होगा, और पते के एलएसबीटी के आधार पर फ़ंक्शन बदलने वाले राज्य में शाखा में बीएक्स का उपयोग करना होगा। इसलिए

mov lr,pc 
bx r1 
here: 

mov एलआर, पीसी ऊपर यहाँ के पते को लोड करता है: जो हमारे वापसी पता, एक राज्य स्वतंत्र ढंग से bx r1 फ़ंक्शन को कॉल है। एलआर पते के lsbit पर लौटने के लिए मोड को इंगित करता है और आप

pre_thumb: 
ldr pc,lr 

thumb_capable: 
bx lr 

संकलक कार्यों फोन करने के लिए एक बीएल अनुदेश आवंटित वापस जाने के लिए हमेशा bx उपयोग करने की आवश्यकता, लिंकर बाद में आराम में भर जाता है, अगर यह बहुत है एक पहुंच के बहुत दूर तो उसे एक ट्रैम्पोलिन फ़ंक्शन की आवश्यकता होती है जो लिंकर स्वयं जोड़ रहा है। इसी तरह यदि आपको मोड बदलने की जरूरत है तो ब्लॉ एक ट्रैम्पोलिन फ़ंक्शन को कॉल करता है जो ऐसा करता है। मैंने मॉडल किया है कि उपर्युक्त में से एक में नकल करने के लिए, आप देख सकते हैं कि यह थोड़ा अपर्याप्त है, उम्मीद है कि संकलक की मेरी स्पष्टीकरण केवल एक ब्लू के लिए स्थान आवंटित करने से अधिक स्पष्ट हो जाती है, जो हमेशा एक मोड परिवर्तन के लिए योजना बनाने के लिए और अधिक स्पष्ट, अपर्याप्त होगा। कोड में अधिकांश फ़ंक्शन कॉल के लिए nops डालना होगा।

कोड भी कोडांतरक में अंगूठे से हाथ करने के लिए एक कॉल में शामिल हैं:

.thumb 

.thumb_func 
.globl XPUT32 
XPUT32: 
    push {lr} 
    ;@ call an arm function from thumb asm 
    ldr r2,=PUT32 
    mov lr,pc 
    bx r2 
    pop {r2} 
    bx r2 

ज्यादातर एक ही छोड़कर आप अंगूठे मोड में एलआर को पॉप नहीं कर सकते, तो आप पीसी के लिए पॉप सकता है, लेकिन मुझे लगता है कि मोड स्विच न , इसलिए आप इसका उपयोग नहीं कर सकते, आपको फिर से एक अतिरिक्त रजिस्टर की आवश्यकता है। आप निश्चित रूप से बुला सम्मेलनों को पता है कि तुम क्या पंजीकृत करता है का उपयोग कर सकते हैं या आप धक्का का एक और सेट लपेट कर सकते हैं पता करने की जरूरत है और सभी लेकिन एलआर संरक्षित करने के लिए पॉप

push {r2,lr} 
    ;@ call an arm function from thumb asm 
    ldr r2,=PUT32 
    mov lr,pc 
    bx r2 
    pop {r2} 
    mov lr,r2 
    pop {r2} 
    bx lr 

अंगूठे अंगूठे या हाथ तुम सिर्फ एक बीएल का उपयोग हाथ करने के लिए यदि आप पहुंच सकते हैं। एलडीआर पीसी, पता अगर आप नहीं कर सकते हैं।

0

यदि आप थंब के रूप में अपना एएसएम कोड इकट्ठा करते हैं, तो आपको फ़ंक्शन को थंब फ़ंक्शन के रूप में चिह्नित करने की आवश्यकता होती है, ताकि लिंकर इसे ब्रांच करते समय सही निर्देश का उपयोग कर सके (उदा। बीएलएक्स या बीएक्स कम बिट सेट वाले पते पर)। यह के साथ किया जाता है।thumb_func निर्देश:

.global activate 
.thumb_func 
activate: 
    b test 

एक अन्य विकल्प स्पष्ट रूप से कोडांतरक पूछने के लिए एआरएम कोड उत्पन्न करने के लिए है:

.code 32 
.global activate 
activate: 
    b test 

चेक this article भी है, हालांकि याद है कि मौजूदा प्रोसेसर कई समाधान है कि ARMv4 में आवश्यक थे की जरूरत नहीं है , तो आप शायद इसे अंधाधुंध पालन नहीं करना चाहिए।

0

भ्रम को समाप्त करने के लिए:

समस्या यह है कि एआरएम के लिए Ubuntu के जीसीसी पार संकलक डिफ़ॉल्ट रूप से अंगूठे (16-बिट) निर्देश उत्पन्न करता था। जैसा कि अन्य उत्तरों यहां दिखाते हैं, दोनों के बीच कॉल करना संभव है, लेकिन जीएनयू असेंबलर ने पाया कि सी कोड अंगूठे निर्देश उत्पन्न कर रहा था और को सी पर कॉल करने के लिए मोड को सही ढंग से सेट करने के लिए बीएक्स का उपयोग करके खुशी से जेनरेट किया गया, मेरे पास कोई नियंत्रण नहीं है जीसीसी स्वयं कार्यों को कॉल करने के लिए जेनरेट करता है, और यह उन्हें सिर्फ ब्लू के साथ बुला रहा था, जो टूट गया क्योंकि मेरा असेंबली कोड एआरएम निर्देश (32-बिट) होना चाहिए।

समाधान (जो खराब दस्तावेज है) जीसीसी-मार्म भेजना है, जो कम से कम सभी कोड एक ही प्रकार का बना देगा।

यदि कार्यों के लिए बीएक्स कॉल उत्पन्न करने के लिए जीसीसी प्राप्त करने के लिए कोई स्विच है, तो शायद यह भी काम करेगा।

+0

gcc -marm मेरे लिए काम नहीं करता है। मुझे arm-v4t-linux-gnueabi –

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