这是我的装配级代码......
section .text
global _start
_start: mov eax, 4
mov ebx, 1
mov ecx, mesg
mov edx, size
int 0x80
exit: mov eax, 1
int 0x80
section .data
mesg db 'KingKong',0xa
size equ $-mesg
输出:
root@bt:~/Arena# nasm -f elf a.asm -o a.o
root@bt:~/Arena# ld -o out a.o
root@bt:~/Arena# ./out
KingKong
我的问题是用于的全球_start是什么?我和Mr.Google试了一下运气,我发现它用来说明程序的起点。为什么我们不能让_start
告诉程序的开始位置,就像下面给出的那个产生一种类型
屏幕上的警告
section .text
_start: mov eax, 4
mov ebx, 1
mov ecx, mesg
mov edx, size
int 0x80
exit: mov eax, 1
int 0x80
section .data
mesg db 'KingKong',0xa
size equ $-mesg
root@bt:~/Arena# nasm -f elf a.asm
root@bt:~/Arena# ld -e _start -o out a.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080
root@bt:~/Arena# ld -o out a.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080
答案 0 :(得分:35)
global
指令是NASM特有的。它用于将代码中的符号导出到生成的目标代码中的位置。在此处标记_start
符号全局,因此其名称将添加到目标代码(a.o
)中。链接器(ld
)可以读取目标代码中的该符号及其值,以便它知道在输出可执行文件中将其标记为入口点的位置。运行可执行文件时,它会从代码中标记为_start
的位置开始。
如果某个符号缺少global
指令,该符号将不会放在目标代码的导出表中,因此链接器无法知道该符号。
如果您想使用与_start
不同的入口点名称(这是默认值),您可以将-e
参数指定为ld,如:
ld -e my_entry_point -o out a.o
答案 1 :(得分:2)
_start
由默认的ld
链接描述文件设置
ld -verbose a.o | grep ENTRY
输出:
ENTRY(_start)
ELF file format(和我想的其他对象格式)明确说明程序将通过e_entry
标题字段开始运行的地址。
ENTRY(_start)
告诉链接器在从目标文件生成ELF文件时将该条目设置为符号_start
的地址。
然后,当OS开始运行程序(Linux上的exec
system call)时,它会解析ELF文件,将可执行代码加载到内存中,并将指令指针设置为指定的地址。
提到的-e
标记by Sedat会覆盖默认的_start
符号。
您还可以使用-T <script>
选项here is a concrete example that sets up some bare metal assembly stuff替换整个默认链接描述文件。
答案 2 :(得分:0)
global _start
只是一个指向内存地址的标签。对于_start,当涉及ELF二进制文件时,它是用作程序启动地址的默认标签。
C语言也知道main
或_main
或main_
,并且“启动代码”调用“通常”链接到 - 如果你是使用C.
希望这有帮助。