2009-09-25 9 views
10

मैं लिनक्स के तहत असेंबलर से शुरू कर रहा हूं। मैंने निम्न कोड को testasm.c
के रूप में सहेजा है और इसे संकलित किया है: gcc testasm.c -otestasm
कंपाइलर उत्तर देता है: "असंभव बाधा 'asm'"।लिनक्स असेंबलर त्रुटि "असंभव बाधा 'asm'

#include <stdio.h> 
int main(void) 
{ 
    int foo=10,bar=15; 

    __asm__ __volatile__ ("addl %%ebx,%%eax" 
     : "=eax"(foo) 
     : "eax"(foo), "ebx"(bar) 
     : "eax" 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 

मैं इस समस्या को कैसे हल कर सकता हूं? (मैं here से उदाहरण कॉपी किया है।)

डेबियन लेनी, कर्नेल 2.6.26-2-amd64
जीसीसी संस्करण 4.3.2 (Debian 4.3.2-1.1)

संकल्प:
स्वीकृत उत्तर देखें - ऐसा लगता है कि 'संशोधित' खंड अब और समर्थित नहीं है।

उत्तर

9
__asm__ __volatile__ ("addl %%ebx,%%eax" : "=a"(foo) : "a"(foo), "b"(bar)); 

काम करने लगता है। मेरा मानना ​​है कि रजिस्टर की बाधाओं के लिए वाक्यविन्यास कुछ बिंदु पर बदल गया है, लेकिन यह बहुत अच्छी तरह से प्रलेखित नहीं है। मुझे कच्ची असेंबली लिखना और परेशानी से बचना आसान लगता है।

+0

यह काम करता है, धन्यवाद। ऐसा लगता है कि इसे अब 'संशोधित' खंड पसंद नहीं है, इसलिए मुझे लगता है कि मुझे जो कुछ भी बदलना है उसे धक्का देना और पॉप करना होगा। – slashmais

+2

संशोधित खंड अभी भी काम करता है; मुझे लगता है कि समस्या यह है कि "आउटपुट" स्पष्ट रूप से "संशोधित" निर्दिष्ट करता है, इसलिए दोनों क्षेत्रों में प्रतिनिधित्व किया गया ईएक्स मुद्दा पैदा कर रहा था। –

0

एक बहु का उपयोग करना चाहता है, तो इस पर भी काम करेंगे ..

__asm__ __volatile__ (
     "addl %%ebx,%%eax; \ 
     addl %%eax, %%eax;" 
     : "=a"(foo) 
     : "a"(foo), "b"(bar) 
    ); 

'\' एक बहु स्ट्रिंग (निर्देश) स्वीकार करने के लिए संकलक के लिए जोड़ा जाना चाहिए।

+0

यह बहुत अच्छी सलाह नहीं है। आप इनपुट और आउटपुट सूचियों में उपयोग किए जाने वाले रजिस्टरों को निर्दिष्ट कर रहे हैं, लेकिन फिर भी वास्तविक असेंबली ब्लॉक के अंदर हार्डकोडेड रजिस्टरों का उपयोग करते हैं। आपको इसके बजाय '% 0' और'% 1' का उपयोग करना चाहिए। –

+0

@DanielKamilKozar: स्वीकृत उत्तर में एक ही पंक्ति में सबकुछ था। इसलिए, मैंने यह दिखाने के लिए समान/समान कोड का उपयोग किया कि इसे मल्टीलाइन में कैसे किया जाए। मैंने मूल स्वीकृत उत्तर में उपयोग किए गए हार्डकोडेड रजिस्टरों को संशोधित करने का प्रयास नहीं किया क्योंकि मैंने सोचा था कि जब कोई मल्टी लाइन से सिंगल की तुलना करता है तो यह समझना आसान होगा। –

5

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

#include <stdio.h> 

int main(void) 
{ 
    int foo=10, bar=15; 

    __asm__ __volatile__ (
     "addl %2, %0" 
     : "=a" (foo) 
     : "0" (foo), "b" (bar) 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 

एक बेहतर समाधान% 2 कुछ भी होने के लिए अनुमति देने के लिए होगा, और% 0 एक रजिस्टर (के रूप में 86 की अनुमति देता है, लेकिन आप करना होगा अपने मशीन मैनुअल की जांच करें):

#include <stdio.h> 

int main(void) 
{ 
    int foo=10, bar=15; 

    __asm__ __volatile__ (
     "addl %2, %0" 
     : "=r" (foo) 
     : "0" (foo), "g" (bar) 
    ); 

    printf("foo = %d", foo); 

    return 0; 
} 
संबंधित मुद्दे