汇编语言中的全局_start是什么?

时间:2013-07-27 14:42:09

标签: assembly nasm

这是我的装配级代码......

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

3 个答案:

答案 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_mainmain_,并且“启动代码”调用“通常”链接到 - 如果你是使用C.

希望这有帮助。