我正在学习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 boson 的答案(对于64位系统)那样完成。如果您想静态地执行此操作,do follow this link(我将从 Z boson 的答案重新发布)。
这是 Jester 发布的关于how programs start in linux的文章。
要查看gcc
与.o
- s相关联的内容,请尝试以下命令:gcc -v -o swap swap.o
。请注意,'v'代表'详细'。
另外,you should read this如果您对64位汇编感兴趣。
感谢您 以获得您的答案和有用的见解!演讲结束。
答案 0 :(得分:6)
以下是使用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。
答案 1 :(得分:2)
如果要调用像atoi
这样的简单库函数,但仍然避免使用C运行库,则可以这样做。 (即你写_start
,而不只是写一个在一堆样板代码运行后被调用的main
。)
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 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