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 32
extern printf
global main
section .data
message db "Hello world!", 10, 0
section .text
main:
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.7
section .text
global start
extern _printf
extern _scanf
extern _exit
start:
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.
EDIT
The 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.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
ld: 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 option
ld: symbol(s) not found for architecture i386
Please help.