加载警告:找不到条目符号_start

时间:2016-01-13 05:07:00

标签: assembly warnings

我正在学习汇编编程。下面是打印'Hello,World!'的简单程序。当程序运行完美时,我在loading

时收到警告消息
  

ld:警告:找不到条目符号_start;默认为0000000008048080

以下是代码:

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使用ubuntu 14

7 个答案:

答案 0 :(得分:5)

您不能说,但是从错误消息和代码中我假设您使用nasm -felf32 hello32.asm && ld -melf_i386 -o hello32 hello32.o构建32位代码

(如果您实际构建的是64位代码,那么您很幸运它会发生工作,但只要您使用esp代替{{rsp执行任何操作,它就会中断1}}。)

错误消息来自ld,而不是来自nasm。它在消息中说得很对。蒂姆的评论是正确的:ld在其链接的文件中查找_start符号,但如果找不到,则将入口点设置为文本段的开头

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

标记为main是不明智的,如果您在没有标准libc运行时启动文件的情况下构建。它的不是 main(),并且没有收到argcargv个参数。 (或者也许32位ABI确实在进程开始时将这些放在堆栈中,按照main()想要的顺序放入堆栈.64位ABI将它们放在堆栈上,但调用main的启动代码必须将它们加载到堆栈中寄存器,因为64位使用寄存器调用ABI。)您也无法从入口点返回:堆栈上没有返回地址。

答案 1 :(得分:1)

我建议您将目标文件(不管它们是否已生成)与date1=`date +%s` while true; do echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r"; done 相关联,而不是#!/bin/bash dir="/tmp/" my_file="generatedscript.sh" rm -rf "$dir$my_file" > /dev/null 2>&1 exec 3>"$dir$my_file" cat >&3 <<-'EOF' #!/bin/bash date1=`date +%s` while true; do echo -ne "Info\n" # this is the damned line, if you remove it the counter works fine echo -ne "Time counter: $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r"; done EOF exec 3>&- xterm -hold -geometry 78x25+0+0 -T "Testing" -e "bash \"$dir$my_file\"" > /dev/null 2>&1 &

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

答案 2 :(得分:1)

我不知道这是否有效,但似乎对我有用:

尝试使用选项

--entry main

在链接您的内核C代码时。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

而不是main,你应该使用_start来指示nasm汇编程序应该从哪里开始执行。 敌人,例如:

section .text
global _start
_start:
mov ebx, 1
mov ecx, msg
mov edx, len
mov eax, 4
int 0x80
mov eax, 1
int 0x80

答案 5 :(得分:0)

要编译和执行程序,您可以按照以下步骤创建bash脚本:

compile64.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)

答案 6 :(得分:-1)

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

在组装程序时,我遇到以下提到的可设置时间错误

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

这是使用32位Intel处理器在gnu编译器上提供相同输出的代码

.section .rodata         msgp:         .string“ Hello World”

    .section .text
    .globl  main
    .type   main,@function

main:
    pushl   $msgp
    call    printf
    addl    $4,%esp

    pushl   $0
    call    exit

使用一些最新名称保存此代码,并输入Hello.S 与...相容 $ as -o Hello.o Hello.S 与...连结 $ ld -o Hello.o -lc-动态链接器/lib.ld.linux.so.2 -e main -Hello.o 跑步 $。/您好

希望它将对您有帮助