0

I learning assembly language, and I have used 'nasm' to compile my .asm file called 'my_program' to a .o file using this command here:

nasm -f elf32 my_program.asm -o my_program.o

As far as I am concerned, this works fine, as a .o file is created. I then do this command:

ld my_program.o -o my_program

Instead of creating a unix executable like it should, this warning/error appears:

ld: warning: platform not specified
ld: warning: -arch not specified
ld: warning: No platform min-version specified on command line
ld: warning: ignoring file my_program.o, building for -unknown but attempting to link with file built for unknown-unsupported file format ( 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 )
Undefined symbols for architecture unknown:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture unknown

Does anyone have any clue why this is happening? Here is the assembly code in the .asm file if it helps (I am just following a tutorial):

global _start
_start:
    mov eax, 1
    mov ebx, 42
    int 0x80
MisterHazza
  • 188
  • 1
  • 10
  • 3
    Your tutorial is for GNU/Linux, which uses ELF object files instead of `macho`, and a slightly different system-call ABI. Find a Mac tutorial or run it on actual Linux in a VM. **Don't try to port your tutorial to MacOS while you're still trying to learn the super-basics from it.** – Peter Cordes Jul 04 '20 at 07:34
  • 2
    This code is 32-bit Linux code which passes arguments in registers. 32-bit MacOS/reeBSD uses the stack. MacOS tool chain uses Macho (for 32-bit Mach it is Macho32), not elf. What happens if you use `-f macho32` with NASM instead of `-f elf32` . It is also possible you are on a MacOS that doesn't even support directly creating or running 32-bit programs anymore.That would be the case if you were using MacOS Catalina or newer OS. – Michael Petch Jul 04 '20 at 07:35
  • Ah I see! What is the difference between elf32 and macho32? Also if Mac does not support 32-bit programs, then would the flag be macho64? – MisterHazza Jul 04 '20 at 07:38
  • 2
    If on a 64-bit only system you'd have to use macho64 and use the proper 64-bit calling convention for system calls. http://www.idryman.org/blog/2014/12/02/writing-64-bit-assembly-on-mac-os-x/ – Michael Petch Jul 04 '20 at 07:41
  • I tries tried running these two commands: ``` % nasm -f macho32 my_program.asm -o my_program.o % ld my_program.o -o my_program ``` ...and I get this error: ``` Undefined symbols for architecture i386: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture i386 ``` – MisterHazza Jul 04 '20 at 07:42
  • Ok, what will that do? – MisterHazza Jul 04 '20 at 07:44
  • Try telling `ld` that your entry point is `_start` with the ld command line option `-e _start` – Michael Petch Jul 04 '20 at 08:00
  • 2
    Go look for a 64-bit NASM tutorial for MacOS and use that instead. I forget if https://stackoverflow.com/tags/x86/info lists any; let me know if you find a good one. (Although beware of NASM bugs on MacOS ([this answer mentions both recent well-known ones](https://stackoverflow.com/a/47301555/224132)); `as` with `.intel_syntax noprefix` might be a better choice). It will have the right commands for assembling and linking. Like I said, don't try to port a 32-bit Linux tutorial to MacOS until after you've already learned most of what it's trying to teach. Then hopefully it will be no problem. – Peter Cordes Jul 04 '20 at 08:01

1 Answers1

0

Change the _start function to _main, the linker expects a _main function just like C++/C expects int main() for .cpp/.c

global _main
_main:
    mov eax, 1
    mov ebx, 42
    int 0x80
halpme
  • 21
  • 4
  • And you've tested this on MacOS with what `nasm` and `ld` commands? The OP was using `nasm -felf32` which is likely going to be a problem on MacOS that expects Mach-O object files. Also, IIRC MacOS's 32-bit `int 0x80` system call ABI matches FreeBSD's - it expects args on the stack, starting with `[esp+4]`. So if you did get this to link, it might exit correctly, but it would `_exit(argc)` instead of the `_exit(42)` the code intends. – Peter Cordes Dec 03 '20 at 16:38