/*********
exit.asm
*/
[SECTION .text]
global _start
_start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80
//****************************
First I used nasm -f elf exit.asm to generate the object file.
then I ran the following "ld" command on my Mac OS X 10.7, it has the these outputs and warning, I tried to run it on my 32 bit linux machine, everything went through just fine, Could you please explain why would not the linker work on my Mac?
Thank you!
Alfred says: ld -o exiter exit.o
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specified, assuming 10.7
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45 0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
"start", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64
after I specify my arch and version, I got:
Alfred says: ld -arch x86_64 -macosx_version_min 10.7 -o exiter exit.o
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45 0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
"start", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
Getting the program to link is the easy part:
_start
tostart
$ nasm -f macho exit.asm
$ ld -arch i386 -o exiter exit.o
The problem is that
exit.asm
is calling the i386 Linuxexit()
system call (EAX = 1) and the program would NOT exit with a zero status as intended on OS X.System Calls
A system call is a request to the kernel.
exit()
, unlikesqrt()
, must make a request to a software component with higher privileges in its implementation since it terminates a running program. Apps can't create or terminate processes by themselves. System calls provide a way for apps to ask the kernel to perform actions on their behalf.Making a syscall goes something like this:
1
in EAX is the system call number ofexit
.0
in EBX (EBX was cleared byxor
) is the first argument to the syscall, the exit status.int 80
on i386sycall
on x86-64svc
in Thumb mode on ARMv7Linux and OS X both provide a
void exit(int)
function for C programs but don't agree on the details on how to describe this request to the kernel. The code inexit.asm
is at the same level as the implementation of the_exit()
function inlibc
.Even between different architectures running Linux the syscall numbers and calling convention differ. e.g. On x86-64 Linux,
exit(0)
is more commonly issued like this:You can see this by disassembling
_exit
in/lib64/libc.so.6
.Can't We Just Call exit() from libc Instead?
You can. But you'd have to link the program with
libc
. It's the difference between linkingexit.asm
above with:and
exit-libc.asm
which has to be linked with:
Try this and take a look at the file size.
Most of the time when you receive this error:
It is because it is looking for your "main()" function(label) to me the label "start:". It is always best to specify the your main label with "ld -e".
For nasm:
For ld:
For Shell:
One-liner:
Let me know if this helps!
I wrote how to do it on my blog here:
http://blog.burrowsapps.com/2013/07/how-to-compile-helloworld-in-intel-x86.html
For a more verbose explanation, I explained on my Github here:
https://github.com/jaredsburrows/Assembly
Mac OS X doesn't use ELF, so you'll want to generate a Mach-O object to link with on that system. On my machine
nasm
appears to only support 32-bit output, so you'll need to match that architecture when linking, too.I also had to change
_start
tostart
to get it to link.Here's a working example with your code:
Note that the program probably doesn't do what you want on Mac OS X, since it doesn't do system calls the same way as Linux.
The standard mac gcc won't link elf objects. For people who need to stick with the elf format and develop on a mac, you need a cross compiler...
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
Then you can proceed with something similar to this...