我正在学习汇编编程。下面是打印'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
。
答案 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()
,并且没有收到argc
和argv
个参数。 (或者也许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 跑步 $。/您好
希望它将对您有帮助