2016-01-25 7 views
5

मैं सी में असेंबली के लिए नया हूं, और मुझे नहीं पता कि इस त्रुटि को कैसे ठीक किया जाए। मैं एक समारोह बना रहा हूं जिसका मतलब है कि एक फाइल लिखना है। मेरे पास क्या है:जब मैं रजिस्टरों का नाम देता हूं तो क्यों असंभव बाधाएं होती हैं?

ssize_t mywrite(int fd, const void *buf, size_t count) { 
// return write(fd, buf, count); 
    ssize_t var; 
    __asm__("movl $4,%%eax\n\t" // Write 
     "movl %1,%%ebx\n\t" 
     "movl %2,%%ecx\n\t" 
     "movl %3,%%edx\n\t" 
     "int $0x80\n\t"   // System call 
     "movl %%eax,%0" 
     :"=r"(var) 
     :"r"(fd),"r"(buf),"r"(count) 
     :"%eax","%ebx","%ecx","%edx" 
    ); 
    return var; 
} 

मेरा एएसएम लिखने के समान ही है (एफडी, बफ, गिनती); जब मैं इसे संकलित करता हूं, तो मुझे "एएसएम 'ऑपरेंड में असंभव बाधाएं मिलती हैं"। हालांकि, यदि चर का नाम नहीं है और सीधे स्टैक से मान प्राप्त करें, तो मुझे कोई त्रुटि नहीं मिलती है। इधर, कोड

__asm__("movl $4,%%eax\n\t" 
     "movl 8(%%ebp),%%ebx\n\t" 
     "movl 12(%%ebp),%%ecx\n\t" 
     "movl 16(%%ebp),%%edx\n\t" 
     "int $0x80\n\t" 
     "movl %%eax,%0" 
     :"=r"(var) 
     : 
     :"%eax","%ebx","%ecx","%edx" 
    ); 

मैं दूसरी कोड का उपयोग कर सकता है ऑप्टिकल फाइबर केबल, लेकिन मैं इसे अनुकूलन 2. साथ संकलित तो% ईबीपी बात नहीं करेंगे, जहां मैं यह करने की जरूरत की जरूरत है। मैंने "आर" के बजाय "ए", "बी", "सी" और "डी" का उपयोग करने की कोशिश की, लेकिन कोई सफलता नहीं। कोई भी मदद कर सकता है? धन्यवाद: डी

+0

क्या आप किसी भी मौके से 64 बिट मोड में संकलित कर रहे हैं? – fuz

उत्तर

7

समस्या यह है कि बाधा r मतलब है रजिस्टर, लेकिन अपने CPU बस इतने सारे रजिस्टर नहीं है!

आप स्मृति बाधा m उपयोग कर सकते हैं:

:"m"(fd),"m"(buf),"m"(count) 

कि इस तरह के रूप निर्देश उत्पन्न करेगा:

movl 8(%ebp),%ebx 

लेकिन मैं अपने सभी महिमा में x86 constraints उपयोग करने के लिए सिफारिश करेंगे:

ssize_t mywrite(int fd, const void *buf, size_t count) { 
    ssize_t var; 
    __asm__(
     "int $0x80" 
     :"=a"(var) 
     :"0"(4), "b"(fd),"c"(buf),"d"(count) 
    ); 
    return var; 
} 

कि, -Ofast के साथ देता है:

push %ebx 
mov $0x4,%eax 
mov 0x10(%esp),%edx 
mov 0xc(%esp),%ecx 
mov 0x8(%esp),%ebx 
int $0x80 
pop %ebx 
ret 

और -Os साथ:

push %ebp 
mov $0x4,%eax 
mov %esp,%ebp 
push %ebx 
mov 0x10(%ebp),%edx 
mov 0x8(%ebp),%ebx 
mov 0xc(%ebp),%ecx 
int $0x80 
pop %ebx 
pop %ebp 
ret  

नोट कैसे, धन्यवाद नाम से रजिस्टर करने के बजाय बाधाओं का उपयोग करने, संकलक आगे कोड का अनुकूलन करने में सक्षम है।

+0

मैंने x86 बाधाओं की कोशिश की और अब यह काम कर रहा है! आपका बहुत बहुत धन्यवाद! इस वैकल्पिक तरीके से जानना बहुत अच्छा है: डी – Behnken

+1

@ बेहेनकेन: ध्यान दें कि लोड-सीधा-से-द-स्टैक तरीका (आपके प्रश्न में दूसरा तरीका) जैसे ही आपका फ़ंक्शन रेखांकित होता है। तो इस तरह से एक विकल्प भी नहीं है, यह सिर्फ टूटा हुआ है। (ओह मुझे लगता है कि आप उस पाठ के आधार पर जानते थे)। आपके प्रश्न में पहला तरीका कोड उत्पन्न करेगा जो डेटा को अन्य रजिस्टरों में लोड करता है, फिर आपके reg-reg move निर्देश चलाता है, इसलिए इसमें आवश्यकतानुसार कई बार निर्देश होंगे। हमेशा के रूप में, जितना संभव हो उतना एएसएम निर्देश लिखो, इसे अपने इनलाइन एएसएम में डेटा/आउट करने के तरीके को चुनने के लिए संकलक को छोड़ दें। –

+0

@ पीटरकॉर्डिस ओह, यह सच है ... मुझे एहसास नहीं हुआ कि वास्तव में पहली बार वास्तव में तोड़ दिया गया था। धन्यवाद: डी यह ध्यान रखना दिलचस्प है कि कोड इस तरह बेहतर अनुकूलित है। जैसा कि मैंने कहा, मैं सीखने के लिए शुरू करने के लिए बहुत नया हूँ, tbh। यह एक सलाह है जो मैं अपने साथ ले जाऊंगा। इसे देने के लिए धन्यवाद! – Behnken

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

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