Reputation: 67
I have some Assembly codes as below: (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
When I compiled it:
as max.s -o max.o
ld -lc -dynamic-linker /lib/ld-linux.so.2 -o max max.o
Then no error occurred.
But when I ran this file by ./max
then this following error occurred: Segmentation fault
Upvotes: 0
Views: 744
Reputation: 113
You are calling exit(3) without passing a return value. The normal way to exit _start from assembler is with a sys_exit system call.
Personally I would use main instead of _start. That way you'll get all of the initialization and cleanup such as flushing the i/o and calling the on_exit code that comes for free with exit(3).
(The only reason you might use your own _start is if you wanted to avoid libc in order to have a smaller executable. There is a discussion of how to do this here https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free ).
Upvotes: 0
Reputation: 213935
The problem is that your program uses libc
functions: printf
and exit
(in addition to ld-linux
), without having properly initialized libc
.
That initialization normally happens in _start
, provided by libc
itself in crt0.o
.
You also mix ix86
and x86_64
calling conventions, and call printf
incorrectly (this is likely the immediate cause of the crash). In 32-bit mode (which you are apparently using), parameters are passed on stack, not in registers.
As Jeff Bell, answered, either rename your _start
to main
and use gcc
instead of ld
to link your program (after fixing your source to use correct calling convention), or get rid of libc
dependencies by implementing printf
and exit
yourself and not linking with ld-linux
and -lc
.
Upvotes: 2