I'm trying to study compilers, for that I have to compile an assembly of a language called howto with nasm.
the intermediate code generated by the howto compiler is as follows:
extern printf segment .text align 8 global main:function main: segment .rodata align 8 _L1: db 'hello', 10, 0 segment .text mov rax, 0 mov edi, $_L1 call printf mov rax, 0 ret
in the OSX terminal I do
$ nasm -f macho out.asm , and I have a compilation error because of the
main:function , if I remove the
:function it ends with this first error when trying to compile again. One more error, but this time it just says I should use
macho64 because of the system architecture, I try to compile with
$ nasm -f macho64 out.asm and I get the error:
out.asm:11: error: Mach-O 64-bit format does not support 32-bit absolute addresses
After that I can't compile anymore, but if I use ELF64 I can create the
From this point with the
out.o file which I must compile with clang, I do
$clang out.o -v to return all the verbose and I get the error:
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) Target: x86_64-apple-darwin14.4.0 Thread model: posix "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.10.0 -o a.out out.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/lib/darwin/libclang_rt.osx.a ld: warning: ignoring file out.o, file was built for unsupported file format ( 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ) which is not the architecture being linked (x86_64): out.o Undefined symbols for architecture x86_64: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
From this point I can't go any further, I tried to link by ld with
$ ld -e _main out.o and
$ ld -e _main out.o -arch x86_64 but in these cases I get the error message:
Undefined symbols for architecture x86_64: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64
On linux, the compilation with
$ nasm -f elf64 out.asm went without problems in the initial form of the code and
$ gcc out.o also generated the a.out file which, when executed, returned the
Hello response of the expected message. However, as I have to finish this project on OSX, I ask the community for help.
I'm not sure what I'm saying!!! but here it goes anyway:
The architecture of intel 80-86 and descendants is a mess!
(unlike linux) on OSX the address space exceeds 2^32 so it doesn't usually support 32-bit absolute addressing.
update : Therefore: use 64bit registers or relative address:
global main extern puts segment .text main: push rbp ; (guardar o frame pointer -- *1) mov rax, 0 mov rdi, _L1 ; usando o registo de 64 bits corresp ao edi call puts pop rbp ; (retaurar o frame pointer -- *1) mov rax, 0 ; (return 0 do C) ret _L1: db "hello", 0
*1lines are not necessary for this case but are good practice…
printfto make it simpler
alternatively — use relative addresses (no best practices…):
global main extern puts segment .text main: mov eax, 0 ; registo de 32 bits correspondente ao rax lea edi, [rel _L1] ; registo de 32 bits... ao rdi call puts ret _L1: db "hello", 0
Untested …I would expect these versions to work on both macho64 (OSX) and elf64 (linux). FEDERAL POLICE. tell me if it works: — I don't have 64bit machines to test