I'm learning x86 assembly on OS X 10.6, how do I compile?
I'm about to learn x86 assembly language on Mac OS X. I'm using as instruction to compile assembly file in commend window. But I have several errors and I don't know how I can get through.
Here are the errors and my assembly code, which is quite simple.
**ung-mi-lims-macbook-pro:pa2 ungmi$ as swap.s
swap.s:16:Unknown pseudo-op: .type
swap.s:16:Rest of line ignored. 1st junk character valued 115 (s).
swap.s:19:suffix or operands invalid for `push'
swap.s:46:suffix or operands invalid for `pop'
ung-mi-lims-macbook-pro:pa2 ungmi$**
and the source is
.text
开发者_如何学Go .align 4
.globl swap
.type swap,@function
swap:
pushl %ebp
movl %esp, %ebp
movl %ebp, %esp
popl %ebp
ret
and I searched some solution which is I have to put -arch i386 than
**ung-mi-lims-macbook-pro:pa2 ungmi$ as -arch i386 swap.s
swap.s:16:Unknown pseudo-op: .type
swap.s:16:Rest of line ignored. 1st junk character valued 115 (s).
ung-mi-lims-macbook-pro:pa2 ungmi$**
Could you help me out? Just let me know what I need to compile assembly file. I have XCode already and I'd rather to do this with commend window and vi editor.
Your code is 32-bit assembly. Compilation on Snow Leopard is 64-bit by default, but you can use gcc -m32
for compiling 32-bit code. There are of course also options that you can pass to as
and ld
but I found that remembering only the option for gcc
was enough, since it is a front-end to all these things.
Use gcc to show you an example of assembly code that works: type a minimal C function in file test.c and use gcc -S test.c
to produce the assembly in file test.s.
Example:
int x;
void f(void)
{
int i;
for (i = 0; i < 5; i++) x = x + 1;
}
is compiled in assembly on this Leopard Mac:
.text
.globl _f
_f:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
call L6
"L00000000001$pb":
L6:
popl %ecx
movl $0, -12(%ebp)
jmp L2
L3:
leal L_x$non_lazy_ptr-"L00000000001$pb"(%ecx), %eax
movl (%eax), %eax
movl (%eax), %eax
leal 1(%eax), %edx
leal L_x$non_lazy_ptr-"L00000000001$pb"(%ecx), %eax
movl (%eax), %eax
movl %edx, (%eax)
leal -12(%ebp), %eax
incl (%eax)
L2:
cmpl $4, -12(%ebp)
jle L3
leave
ret
.comm _x,4,2
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L_x$non_lazy_ptr:
.indirect_symbol _x
.long 0
.subsections_via_symbols
You can make it simpler by using gcc option -fno-PIC:
.text
.globl _f
_f:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $0, -12(%ebp)
jmp L2
L3:
movl _x, %eax
incl %eax
movl %eax, _x
leal -12(%ebp), %eax
incl (%eax)
L2:
cmpl $4, -12(%ebp)
jle L3
leave
ret
.comm _x,4,2
.subsections_via_symbols
On Snow Leopard you will get 64-bit assembly (amd64). You could get the same thing on Leopard by using the -m64 gcc option, and you can get on Snow Leopard the same thing you'd get running gcc on Leopard with the -m32 option.
Use GCC, it'll compile and link for you: cc swap.s
Apple's as
is forked from binutils 1.38, while the current version is 2.20, so there may be many new directives not available. I can't find the manual for 1.38, but the oldest one (2.10) I could find states that .type
is associated only with COFF format output. The object format on Mac is Mach-O, so the .type
directive is meaningless. Just remove it.
Recently I have ran in to this issue as well trying to compile Intel x86 on Mac OS X:
For nasm:
-o hello.tmp - outfile
-f macho - specify format
Linux - elf or elf64
Mac OSX - macho
For ld:
-arch i386 - specify architecture (32 bit assembly)
-macosx_version_min 10.6 (Mac OSX - complains about default specification)
-no_pie (Mac OSX - removes ld warning)
-e main - specify main symbol name (Mac OSX - default is start)
-o hello.o - outfile
For Shell:
./hello.o - execution
One-liner:
nasm -o hello.tmp -f macho hello.s && ld -arch i386 -macosx_version_min 10.6 -no_pie -e _main -o hello.o hello.tmp && ./hello.o
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
精彩评论