但是,当我删除行 .globl _start ...
.globl 行表示名称 _start 在文件 file.s 之外是“可见的”。如果删除该行,名称 _start 仅用于文件 file.s 中,在更大的程序(包含多个文件)中,您甚至可以在多个文件中使用名称 _start。
(这类似于 C/C++ 中的static 变量:如果你从 C 或 C++ 生成汇编代码,真正的全局变量和static 变量之间的区别在于全局变量有一个.globl 行变量,而static 变量没有.globl 行。而且如果你熟悉C,就知道static 变量不能在其他文件中使用。)
链接器 (ld) 也不能使用名称 _start,如果它只能在文件中使用的话。
0000000000400078 是什么意思?
显然0x400078 是程序第一个字节的地址。如果没有找到名为 _start 的符号,ld 假定程序从第一个字节开始。
...为什么还要声明.globl _start?
不保证_start 位于程序的第一个字节。
反例:
.globl _start
write_stdout:
mov $4, %eax
mov $1, %ebx
int $0x80
ret
exit:
mov $1, %eax
mov $0, %ebx
int $0x80
jmp exit
_start:
mov $text, %ecx
mov $(textend-text), %edx
call write_stdout
mov $text2, %ecx
mov $(textend2-text2), %edx
call write_stdout
call exit
text:
.ascii "Hello\n"
textend:
text2:
.ascii "World\n"
textend2:
如果您删除 .globl 行,ld 将无法找到 _start: 行并假设您的程序从第一个字节开始 - 即 write_stdout: 行!
...如果您在一个较大的程序中有多个.s 文件(或者甚至是.s、.c 和.cc 的组合),则您无法控制哪个代码位于程序的第一个字节!