Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22113

How do you call C functions from Assembly and how do you link it Statically?

$
0
0

I am playing around and trying to understand the low-level operation of computers and programs. To that end, I am experimenting with linking Assembly and C.

I have 2 program files:

Some C code here in "callee.c":

#include <unistd.h>void my_c_func() {  write(1, "Hello, World!\n", 14);  return;}

I also have some GAS x86_64 Assembly here in "caller.asm":

.text.globl my_entry_ptmy_entry_pt:  # call my c function  call my_c_func # this function has no parameters and no return data  # make the 'exit' system call  mov $60, %rax # set the syscall to the index of 'exit' (60)  mov $0, %rdi # set the single parameter, the exit code to 0 for normal exit  syscall

I can build and execute the program like this:

$ as ./caller.asm -o ./caller.obj$ gcc -c ./callee.c -o ./callee.obj$ ld -e my_entry_pt -lc ./callee.obj ./caller.obj -o ./prog.out -dynamic-linker /lib64/ld-linux-x86-64.so.2$ ldd ./prog.out    linux-vdso.so.1 (0x00007fffdb8fe000)    libc.so.6 => /lib64/libc.so.6 (0x00007f46c7756000)    /lib64/ld-linux-x86-64.so.2 (0x00007f46c7942000)$ ./prog.outHello, World!

Along the way, I had some problems. If I don't set the -dynamic-linker option, it defaults to this:

$ ld -e my_entry_pt -lc ./callee.obj ./caller.obj -o ./prog.out$ ldd ./prog.out    linux-vdso.so.1 (0x00007ffc771c5000)    libc.so.6 => /lib64/libc.so.6 (0x00007f8f2abe2000)    /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f8f2adce000)$ ./prog.outbash: ./prog.out: No such file or directory

Why is this? Is there a problem with the linker defaults on my system? How can/should I fix it?

Also, static linking doesn't work.

$ ld -static -e my_entry_pt -lc ./callee.obj ./caller.obj -o ./prog.outld: ./callee.obj: in function `my_c_func':callee.c:(.text+0x16): undefined reference to `write'

Why is this? Shouldn't write() just be a c library wrapper for the syscall 'write'? How can I fix it?

Where can I find the documentation on the C function calling convention so I can read up on how parameters are passed back and forth, etc...?

Lastly, while this seems to work for this simple example, am I doing something wrong in my initialization of the C stack? I mean, right now, I'm doing nothing. Should I be allocing memory from the kernel for the stack, setting bounds, and setting %rsp and %rbp before I start trying to call functions. Or is the kernel loader taking care of all this for me? If so, will all architectures under a Linux kernel take care of it for me?


Viewing all articles
Browse latest Browse all 22113

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>