我有一些汇编代码如下:(max.s file)
.section .data
d1: .double 12.5
d2: .double 6.5
formatstr: .asciz "Max value is: %lf\n"
.section .text
.globl _start
_start:
movsd d1,%xmm0
movsd d2,%xmm1
ucomisd %xmm1,%xmm0
ja endif
then:
movsd %xmm1,%xmm0
endif:
mov $formatstr,%edi
mov $1,%eax
call printf
call exit
编译时:
as max.s -o max.o
ld -lc -dynamic-linker /lib/ld-linux.so.2 -o max max.o
然后没有发生错误。
但是当我按./max
运行此文件时,发生以下错误:分段错误
答案 0 :(得分:2)
问题是,您的计划使用libc
个功能:printf
和exit
(除了ld-linux
),而没有正确初始化libc
。< / p>
初始化通常发生在_start
,由libc
本身在crt0.o
中提供。
您还混合ix86
和x86_64
调用约定,并错误地调用printf
(这可能是导致崩溃的直接原因)。在32位模式(您显然使用它)中,参数在堆栈上传递,而不是在寄存器中传递。
正如杰夫贝尔回答的那样,要么将您的_start
重命名为main
并使用gcc
代替ld
来关联您的计划(修复您的来源以使用正确的通话后)通过自己实现libc
和printf
而不是与exit
和ld-linux
链接来摆脱-lc
依赖关系。
答案 1 :(得分:0)
您正在调用exit(3)而不传递返回值。从汇编程序退出_start的常规方法是使用sys_exit系统调用。
我个人会使用 main 而不是 _start 。这样你就可以获得所有的初始化和清理工作,例如刷新i / o并使用exit(3)调用免费提供的on_exit代码。
(您可能使用自己的_start的唯一原因是,如果您想要避免使用libc以获得较小的可执行文件。这里讨论了如何执行此操作https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free)。