Search code examples
linuxgccassemblynasmld

How to link the C Runtime Library with 'ld'?


I'm learning assembly with NASM for a class I have in college. I would like to link the C Runtime Library with ld, but I just can't seem to wrap my head around it. I have a 64 bit machine with Linux Mint installed.

The reason I'm confused is that -- to my knowledge -- instead of linking the C runtime, gcc copies the things that you need into your program. I might be wrong though, so don't hesitate to correct me on this, please.

What I did up to this point is, to link it using gcc. That produces a mess of a machine code that I'm unable to follow though, even for a small program like swapping rax with rbx, which isn't that great for learning purposes. (Please note that the program works.)

I'm not sure if it's relevant, but these are the commands that I'm using to compile and link:

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

Thank you in advance!


Conclusion:

Now that I have a proper answer to the question, here are a few things that I would like to mention. Linking glibc dynamically can be done like in Z boson's answer (for 64 bit systems). If you would like to do it statically, do follow this link (that I'm re-posting from Z boson's answer).

Here's an article that Jester posted, about how programs start in linux.

To see what gcc does to link your .o-s, try this command out: gcc -v -o swap swap.o. Note that 'v' stands for 'verbose'.

Also, you should read this if you are interested in 64 bit assembly.

Thank you for your answers and helpful insight! End of speech.


Solution

  • Here is an example which uses libc without using GCC.

    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
    

    Compile and link like this:

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

    This has worked fine so far for me but for static linkage it's complicated.