2011-12-31 9 views
9

मैं मुसीबत 2 वस्तु फ़ाइलों जिनमें से एक एक विधानसभा भाषा स्रोत फ़ाइल से बनाया गया था और एक अन्य है कि एक सी स्रोत फ़ाइल से किया गया था जोड़ने हो रहा है।किसी ऑब्जेक्ट फ़ाइल को असेंबली भाषा ऑब्जेक्ट फ़ाइल से कैसे लिंक करें?

सी स्रोत कोड:

//main2.c 
extern int strlength(char *); 
int main(){ 
    char * test = "hello"; 
    int num = strlength(test); 
    return num; 
} 

विधानसभा स्रोत कोड:

#strlength.s 
.include "Linux32.s" 

.section .text 
.globl strlength 
.type strlength, @function 
strlength: 
pushl %ebp 
movl %esp, %ebp 
movl $0, %ecx 
movl 8(%ebp), %edx 
read_next_byte: 
movb (%edx), %al 
cmpb $END_OF_FILE, %al 
jle end 
incl %edx 
incl %ecx 
jmp read_next_byte 
end: 
movl %ecx, %eax 
popl %ebp 
ret 

जब मैं संकलन और रन 'जीसीसी' का उपयोग इस तरह:

gcc main2.c strlength.s -m32 -o test 
./test 
echo $? 

मैं 5 मिलता है जो सही बात। लेकिन जब मैं संकलन/अलग से इकट्ठा और फिर 'ld' इस तरह के साथ लिंक:

as strlength.s --32 -o strlength.o 
cc main2.c -m32 -o main2.o 
ld -melf_i386 -e main main2.o strlength.o -o test 
./test 

मैं एक विभाजन गलती मिलता है। इसके उत्पन्न होने का कारण क्या है? क्या मैं सी कॉलिंग सम्मेलन का 100% सही तरीके से पालन नहीं कर रहा हूं?

उत्तर

11

ld -melf_i386 -e main main2.o strlength.o -o test

कि ऐसा मत करो। इस के बजाय कार्य करें:

gcc -m32 main2.o strlength.o -o test 

(आप शायद, अपने परीक्षण exectuable test नहीं बुलाना चाहिए के रूप में यह, /bin/test साथ अंतर्विरोध कर सकते सबसे यूनिक्स सिस्टम पर मानक।)

स्पष्टीकरण: यूनिक्स binaries आम तौर पर कर नहींmain पर निष्पादन शुरू करें। वे एक समारोह _start कहा जाता है, जो crt1.o या इसी तरह के ("सी रनटाइम स्टार्टअप") से आता है में क्रियान्वित करने लगते हैं। कि फ़ाइल libc का हिस्सा है, और यह विभिन्न initializations, अपने आवेदन के ऊपर उचित शुरू करने के लिए आवश्यक के लिए व्यवस्था।

आपका कार्यक्रम वास्तव में libc से कुछ भी है, जो तुम क्यों ld के साथ लिंक करने में सक्षम थे आवश्यकता नहीं है।

हालांकि, विचार करें कि आपके main रिटर्न के बाद क्या होता है। आम तौर पर, crt1.o में कोड exit(main(argc, argv)); निष्पादित करेगा (समकक्ष)। चूंकि आपने crt1.o के बिना लिंक किया है, इसलिए आपके लिए अंतिम exit ऐसा करने के लिए कोई भी नहीं है, इसलिए कोड वापस आ गया है ... अपरिभाषित स्थान और तुरंत क्रैश हो जाता है।

4

तुम भी crt1.o (एक अलग नाम हो सकता है, ऊपर आवश्यक कोड होता है जब तक main कहा जा सकता है) और आवश्यक पुस्तकालयों लिंक करना होगा। जीसीसी को आमतौर पर libgcc.so से लिंक करने की आवश्यकता होती है जिसमें आवश्यक सहायक कार्य होते हैं (उदाहरण के लिए, 32 बिट सिस्टम पर 64 बिट गणना करते समय) और अन्य सिस्टम लाइब्रेरीज़। उदाहरण के लिए, मेरे मैक पर, इसे libSystem से लिंक करने की भी आवश्यकता है जिसमें सामान्य सी फ़ंक्शन जैसे printf भी शामिल हैं। लिनक्स पर, यह आमतौर पर libc है।

ध्यान रखें कि आपके कार्यक्रम सीधे main के साथ शुरू नहीं कर सकते हैं (जैसा कि आप ld .. -e main साथ के साथ क्या करने की कोशिश कर रहे हैं), प्रवेश बिंदु से पहले सी समारोह main बुला के लिए कुछ चीजें स्थापित करने के लिए की जरूरत है। पहले उल्लेख किया गया crt1.o ऐसा कर रहा है। मुझे लगता है कि सेगमेंटेशन गलती इस लापता सेटअप का परिणाम है।

क्या जीसीसी बिल्कुल आपके सिस्टम पर कर रहा है देखने के लिए, फोन:

gcc main2.c strlength.s -m32 -o test -v 
संबंधित मुद्दे