我正在学习用NASM
组装一类我在大学。我想C运行时库与ld
联系,但我似乎无法环绕它我的头。我有一个64 bit
机安装Linux Mint
。
我感到困惑的原因是 - 我的知识 - 而不是链接的C运行时,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
动态可以像沿Z玻色子的答案来完成(64位系统)。如果你想做到这一点静态,do follow this link(我是从ž玻色子的答案重新张贴)。
下面是小丑贴,约how programs start in linux的文章。
要查看gcc
做链接您的.o
-S是什么,试试这个命令了:gcc -v -o swap swap.o
。请注意,“V”代表“冗长”。
此外,you should read this如果你有兴趣在64位汇编。
感谢您的答案和有益的见解!演讲结束。
这里是使用libc
而不使用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
编译和链接如下:
nasm -f elf64 hello.asm
ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -m elf_x86_64
这对我而且对static linkage it's complicated工作的罚款为止。
如果你想调用简单的库函数一样atoi
,但仍避免使用C运行时,你可以做到这一点。 (即你写_start
,而不是仅仅写那被一堆的锅炉板代码运行后称为main
。)
gcc -o swap -nostartfiles swap.o
随着人们在评论中说,glibc的某些部分依赖于从标准的启动文件运行构造函数/析构函数。也许这是一个标准输入输出(看跌期权/的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 exit@@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