_start的默认值

问题描述

假设我有以下汇编程序:

     {"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的组合),则不会控制哪些代码位于程序的第一个字节!