Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 加载警告:找不到输入符号\u start_Linux_Assembly_Warnings_Nasm_Ld - Fatal编程技术网

Linux 加载警告:找不到输入符号\u start

Linux 加载警告:找不到输入符号\u start,linux,assembly,warnings,nasm,ld,Linux,Assembly,Warnings,Nasm,Ld,我在学习汇编编程。下面是打印“你好,世界!”的简单程序。程序运行正常时,我在加载时收到警告消息 ld:警告:找不到输入符号\u start;默认为000000000 8048080 代码如下: section .data msg db 'Hello, world!', 0xa len equ $ - msg section .text global main main: mov ebx, 1 mov ecx, msg mov edx, len

我在学习汇编编程。下面是打印“你好,世界!”的简单程序。程序运行正常时,我在加载时收到警告消息

ld:警告:找不到输入符号\u start;默认为000000000 8048080

代码如下:

section .data
    msg db 'Hello, world!', 0xa
    len equ $ - msg

section .text
    global main

main:

    mov ebx, 1
    mov ecx, msg
    mov edx, len
    mov eax, 4
    int 0x80

    mov eax, 1
    int 0x80

谁能解释一下这个警告的含义吗。我正在将
nasm
ubuntu14
一起使用

使用标签
\u start
而不是
main
作为ELF入口点。
main
意味着它类似于C
main
函数,但它甚至不是一个函数(例如)


您没有说,但根据错误消息和代码,我假设您正在使用
nasm-felf32 hello32.asm&&ld-melf_i386-o hello32 hello32.o构建32位代码

(如果您实际构建的是64位代码,那么幸运的是它正好工作,但只要您使用
esp
而不是
rsp
执行任何操作,它就会崩溃)

错误消息来自
ld
,而不是来自
nasm
。这句话在信息里说得很对。Tim的评论是正确的:
ld
在它链接的文件中查找
\u start
符号,但如果没有找到,则将入口点设置为文本段的开头

您定义的其他全局/外部符号并不重要
main
在这里没有任何关联,可以指向任何你想要的地方。它只对反汇编输出和类似的东西有用。如果取出
global main
/
main:
行,或者将它们更改为任何其他名称,则代码的工作原理完全相同


将其标记为
main
是不明智的,因为ELF入口点不是函数。它不是
main()
,不接收
argc
argv
参数,也不能
ret
,因为ESP指向的是
argc
,而不是返回地址

仅当您链接到gcc/glibc的CRT启动代码,该代码查找
main
符号并在初始化libc后调用它时,才使用
main
。(所以像printf这样的函数可以工作。技术上,动态链接器钩子允许libc在
\u启动之前进行初始化,如果您链接了它,但通常不会这样做,除非您完全理解自己在做什么)。相关的:

e、 g.
gcc-m32-o hello main.o
如果定义了
main:

而不是
gcc-m32-static-nostlib-o hello start.o


(这相当于您的裸
ld
)。

我建议您将对象文件(无论它们是如何生成的)链接到
gcc
,而不是
ld


gcc
将使用适当的选项调用
ld
,因为它了解更多关于源代码的信息,并将创建
ld
所做假设所需的任何内容。

您可以尝试使用nasm编译程序集源文件,生成*.o文件,然后使用ld链接带有参数-e main的*.o文件。这意味着main被指定为程序条目。

您应该使用_start来指示nasm汇编程序应该从哪里开始执行。 例如:


您的程序中存在一些问题,例如 一些语法错误,比如不能将寄存器的值赋给常量,因为常量不能保存任何值,为了存储常量值,我们使用变量

在汇编程序时,我遇到了下面提到的可接受的时间错误

没有这样的指令:
msg db 72ello,world!440xa'
assign.S:3:错误:没有这样的指令:
leneq$-msg' assign.S:4:错误:没有此类指令:
section.text'
assign.S:5:错误:没有此类指令:
global main' assign.S:7:错误:
mov'的内存引用过多
assign.S:8:错误:mov的内存引用过多
assign.S:9:错误:
mov'的内存引用过多
assign.S:10:错误:mov的内存引用过多
assign.S:11:错误:
int'的操作数大小不匹配
assign.S:12:错误:mov的内存引用过多
assign.S:13:错误:“int”的操作数大小不匹配

下面的代码在32位英特尔处理器的gnu编译器上提供相同的输出

.第节.罗达 msgp: .字符串“Hello World”

用最新名称保存此代码take Hello.S 赞同 $as-o你好。o你好。S 联系 $ld-o Hello.o-lc-dynamiclinker/lib.ld.linux.so.2-emain-Hello.o 运行 美元/你好


希望它能帮助您编译和执行您可以创建的
bash
脚本,如下所示:

编译64.sh

!/bin//bash
echo "Assembling with Nasm"
nasm -f elf64 -o $1.o $1.asm
echo "Linking ... "
gcc -o $1 $1.o
echo "Done !"

$ ./compile64 nameOftheFile  (without extension)

我不知道这是否是一个有效的解决方案,但似乎对我有效:

尝试使用选项

--entry main
链接内核C代码时

ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary --entry main 

我不是汇编专家,但我相信汇编程序正在寻找一个名为
\u start
的入口点(它找不到,因为它不在那里)。堆栈溢出似乎已经很成熟,有很多类似的问题,所以请四处搜索。@TimBiegeleisen实际上我也这么认为。但我不明白的是为什么它与
main
一起工作。如果要显式地启动,为什么要通过警告而不是错误执行
nasm
。我在谷歌上搜索了一下,发现每个人都在他们的汇编代码中使用
start\uu
关键字,但为什么它使用
main
关键字。“为什么nasm通过警告而不是错误”。从我所看到的警告来自链接器,而不是nasm。链接器找不到入口点,因此它可能默认为
.text
部分的开头。相关:事实上,在我使用的教程中,他们使用了
main
而不是
start\ucode>@Atinesh:那么您应该使用
gcc-m32-o hello32.o
来构建,而不是

--entry main
ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary --entry main