I have spent the entire day trying to get some simple programs compiled but so far very little luck. What I want to do is to compile and run programs written in nasm assembly.
I have upgraded to latest nasm (v2.10.09). So let me just jump into code since I do not know a lot about these things yet. Here is a chunk of assembly code that runs on linux using elf
format and linked witch gcc (comments are my understanding of what is going on):
bits 32extern printfglobal mainsection .data message db "Hello world!", 10, 0section .textmain: pushad ;push all registers on stack push dword message ;push the string on stack call printf ;call printf add esp, 4 ;clear stack popad ;pop all registers back ret ;return to whoever called me
Nothing too big. However how the hell am I supposed to get this to work on OS X? I cant even get it to compile/link in any way. If it compiles I cant link it (something about i386 and x86 which cant be linked together (I understand that but how to fix it?)). I have tried a dozen ways with no luck.
Further more how can I printf
and scanf
on OS X assembly?
Here is another futile attempt of a scanf
and printf
the value back (this one actually compiles and links - and even runs!):
[bits 32] ; why the []?section .data input_string db "Enter limit: %d", 0 output_string db "Value %d", 10, 0 counter dd 10 limit dd 0;nasm -f macho -o test.o test.asm ;ld -lc -o test -arch i386 test.o -macosx_version_min 10.7section .textglobal startextern _printfextern _scanfextern _exitstart: push ebp ;push stack base mov ebp, esp ;base is now current top and esp, 0xFFFFFFF0 ;align the stack - WHY? I just googled this? sub esp, 16 ;16 bytes for variables - 16 to keep the stack "aligned". WHY? mov dword[esp], input_string ;ordinary push just isint good nuff for mac... WHY? mov dword[esp + 4], limit call _scanf ;does scan something but doesnt print the message, it just scans and then prints the message mov eax, [limit] ;since i cant push this lets put it in eax first mov dword[esp + 8], output_string ;push the output string. WHY again MOV? mov dword[esp + 12], eax ;and the previusly "scanned" variable call _printf ;print it out mov dword[esp], 0 ;return value call _exit ;return
Compiled it with: nasm -f macho -o test.o test.asm
and linked it with d -lc -o test -arch i386 test.o -macosx_version_min 10.7
. Doesnt work properly. On linux its super easy to to this scanf and printf thingie. What's up here? Can it be done simpler?
I do not want to add more stuff to this question since people sometimes see a big question and thing "meh, too long, wont read". But if anyone requests more info I'll do my best.
Please help me since I cant figure it out.
EDITThe first one compiles using nasm -f macho -o out.o test.asm
but doest link using gcc -o test out.o
or by using ld -lc -o test -arch i386 out.o -macosx_version_min 10.7
and appending flat -arch i386
doesnt solve it either. I would love if I could write that "linux like" assembly since I do not have to worry about stack alignment and stuff like that.gcc error says:
ld: warning: ignoring file out.o, file was built for i386 which is not the architecture being linked (x86_64): out.oUndefined symbols for architecture x86_64:"_main", referenced from: start in crt1.10.6.old: symbol(s) not found for architecture x86_64
and ld error is as follows:
Undefined symbols for architecture i386:"printf", referenced from: main in out.o"start", referenced from: -u command line optionld: symbol(s) not found for architecture i386
Please help.