问题描述
假设我有以下汇编程序:
{"shortcuts":
[
{
"command": "notebook:move-cell-up","keys": [
"Ctrl U"
],"selector": ".jp-Notebook:focus"
}
]
}
我将其组装/链接为:
.globl _start
_start:
mov $1,%eax
int $0x80
这将正常运行,并将状态代码0返回给linux。但是,当我删除行$ as file.s
$ ld a.out -o a
时,出现以下错误:
.globl start
:警告:找不到条目符号ld
;默认为_start
0000000000400078
是什么意思?而且,如果0000000000400078
在输入时期望使用ld
符号,为什么还要声明_start
呢?
解决方法
但是,当我删除行
.globl _start
...
.globl
行意味着名称_start
在文件file.s
之外是“可见的”。如果删除该行,则名称_start
仅在文件file.s
内部使用,而在较大的程序(包含多个文件)中,您甚至可以在多个文件中使用名称_start
。
(这类似于C / C ++中的static
变量:如果从C或C ++生成汇编代码,则实际全局变量和static
变量之间的区别是存在一个{{1 }}行用于全局变量,而.globl
行则用于.globl
变量。如果您熟悉C,就知道static
变量不能在其他文件中使用。)>
如果链接器(static
)仅可在文件内部使用,则也无法使用名称ld
。
_start
是什么意思?
显然0000000000400078
是程序的第一个字节的地址。如果找不到名为0x400078
的符号,ld
假定程序从第一个字节开始。
...为什么甚至需要声明
_start
?
不能保证.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
行,并假定程序从第一个字节-{{1} }行!
...,并且如果您在一个较大的程序中有多个_start:
文件(甚至是write_stdout:
,.s
和.s
的组合),则不会控制哪些代码位于程序的第一个字节!