2015-12-06 12 views
9

मैं कॉलेज में कक्षा के लिए NASM के साथ असेंबली सीख रहा हूं। मैं ld साथ सी रनटाइम लाइब्रेरी लिंक करना चाहते हैं, लेकिन मैं सिर्फ यह आसपास मेरे सिर लपेटो नहीं कर पा रहे। मेरे पास स्थापित 64 bit मशीन है।सी रनटाइम लाइब्रेरी को 'एलडी' से कैसे लिंक करें?

कारण मैं उलझन में हूं कि - मेरे ज्ञान के लिए - सी रनटाइम को जोड़ने के बजाय, gcc आपके प्रोग्राम में आवश्यक चीजों की प्रतिलिपि बनाता है। हालांकि मैं गलत हो सकता हूं, इसलिए कृपया मुझे इस पर सही करने में संकोच न करें।

क्या मैं ऊपर किया था करने के लिए इस बिंदु है, यह gcc का उपयोग कर से जोड़ने के लिए। यह एक मशीन कोड की गड़बड़ी पैदा करता है जिसे मैं पालन करने में असमर्थ हूं, यहां तक ​​कि rax को rbx के साथ स्वैपिंग जैसे छोटे कार्यक्रम के लिए, जो सीखने के उद्देश्यों के लिए बहुत अच्छा नहीं है। (कृपया ध्यान दें कि कार्यक्रम काम करता है।)

मैं अगर यह प्रासंगिक है यकीन नहीं है, लेकिन इन आदेशों को मैं संकलित करने के लिए उपयोग कर रहा हूँ और कड़ी कर रहे हैं:

# compilation 
nasm -f elf64 swap.asm 
# gcc 
gcc -o swap swap.o 
# ld, no c runtime 
ld -s -o swap swap.o 

अग्रिम धन्यवाद!


निष्कर्ष:

अब जब कि मैं प्रश्न के लिए एक उचित जवाब है, यहाँ कुछ चीजें हैं जो मैं उल्लेख करना चाहते हैं कर रहे हैं। glibc को जोड़ने से जेड बोसन के उत्तर (64 बिट सिस्टम के लिए) की तरह गतिशील रूप से किया जा सकता है। आप इसे स्थिर (जेड बोसॉन के जवाब से है कि मैं कर रहा हूँ फिर से पोस्टिंग) do follow this link क्या करना चाहते हैं, तो।

यहां एक लेख है कि जेस्टर पोस्ट किया गया, लगभग how programs start in linux

यह देखने के लिए कि gcc आपके .o -s को लिंक करने के लिए करता है, इस आदेश को आजमाएं: gcc -v -o swap swap.o। ध्यान दें कि 'v' 'verbose' के लिए खड़ा है।

इसके अलावा, you should read this अगर आप 64 बिट विधानसभा में रुचि रखते हैं।

अपने जवाब और उपयोगी जानकारी के लिए धन्यवादआप! भाषण का अंत

+2

संक्षिप्त उत्तर: नहीं। दुर्भाग्य से libc न केवल गतिशील पुस्तकालय के साथ आता है, लेकिन प्रारंभिक वस्तुओं और शट डाउन के लिए आवश्यक स्थिर वस्तुओं का एक गुच्छा। यदि आप वास्तव में ऐसा करना चाहते हैं, तो यह देखने के लिए कि आवश्यक भाग क्या हैं, 'gcc -v' का उपयोग करें। आपको इस कार्यक्रम में रुचि हो सकती है [प्रोग्राम स्टार्टअप के बारे में शानदार लेख] (http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html)। – Jester

+0

'gcc -o swap swap.o' रनटाइम को लिंक करता है। 'ld -o स्वैप swap.o' नहीं करता है। लिंकिंग में रनटाइम के बड़े-आइस हिस्सों को निष्पादन योग्य पर कॉपी करना शामिल है। वास्तव में समस्या क्या है? –

+0

@ जेस्टर मैं अभी उसमें देख लूंगा! – mrDudePerson

उत्तर

4

यहाँ एक उदाहरण है जो जीसीसी का उपयोग किए बिना libc का उपयोग करता है।

extern printf 
extern _exit 

section .data 
    hello:  db 'Hello world!',10 

section .text 
    global _start 
_start: 
    xor eax, eax 
    mov edi, hello 
    call printf 
    mov rax, 0  
    jmp _exit 

संकलित करें और लिंक इस तरह:

nasm -f elf64 hello.asm 
ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64 

यह मेरे लिए लेकिन static linkage it's complicated के लिए अब तक ठीक काम किया है।

+0

धन्यवाद, मैं बाद में इसे आजमाउंगा। अगर यह काम करता है, तो मैं इसे सही उत्तर के रूप में चुनूंगा :) – mrDudePerson

+0

हां, यह काम करता है! धन्यवाद :) – mrDudePerson

2

आप atoi की तरह साधारण पुस्तकालय कार्यों कॉल करने के लिए, लेकिन अभी भी सी क्रम का उपयोग कर से बचने चाहते हैं, आप ऐसा कर सकते हैं। (यानी आप सिर्फ एक main बॉयलर-प्लेट कोड के एक झुंड के बाद कहा जाता हो जाता है कि चलाता है लिखने की तुलना में _start लिखते हैं, बल्कि।)

gcc -o swap -nostartfiles swap.o 

के रूप में लोगों को टिप्पणी में कहते हैं, glibc के कुछ भागों निर्माताओं पर निर्भर/विनाशकर्ता से चलाने मानक स्टार्टअप फाइलें। शायद यह stdio (puts/printf/scanf/getchar), और शायद malloc के लिए मामला है। बहुत से फ़ंक्शन "शुद्ध" फ़ंक्शंस हैं जो केवल उनके द्वारा दिए गए इनपुट को संसाधित करते हैं। sprintf/sscanf उपयोग करने के लिए ठीक हो सकता है।

उदाहरण के लिए:

$ cat >exit64.asm <<EOF 
section .text 

extern exit 

global _start 
_start: 

    xor edi, edi 
    jmp exit   ; doesn't return, so optimize like a tail-call 

    ;; or make the syscall directly, if the jmp is commented 
    mov eax, 231 ; exit(0) 
    syscall 

; movl eax, 1  ; 32bit call 
; int 0x80 
EOF 

$ yasm -felf64 exit64.asm && gcc -nostartfiles exit64.o -o exit64-dynamic 
$ nm exit64-dynamic 
0000000000601020 D __bss_start 
0000000000600ec0 d _DYNAMIC 
0000000000601020 D _edata 
0000000000601020 D _end 
       U [email protected]@GLIBC_2.2.5 
0000000000601000 d _GLOBAL_OFFSET_TABLE_ 
00000000004002d0 T _start 
$ ltrace ./exit64-dynamic 
enable_breakpoint pid=11334, addr=0x1, symbol=(null): Input/output error 
exit(0 <no return ...> 
+++ exited (status 0) +++ 
$ strace ... # shows the usual system calls by the runtime dynamic linker 
+0

हां, धन्यवाद, यह सही होगा! :) – mrDudePerson

+0

@mrDudePerson: अपनी समस्या का हल करने वाले उत्तर को "स्वीकार" न भूलें। (ऊपर/नीचे वोट तीर के नीचे चेकबॉक्स पर क्लिक करें)। अन्यथा सवाल अभी भी अनुत्तरित के रूप में दिखाई देता है। –

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