basic assembly not working on Mac (x86_64+Lion)?

冷暖自知 提交于 2019-12-17 09:54:14

问题


here is the code(exit.s):

.section .data,
.section .text,
.globl _start
_start:
    movl $1, %eax
    movl $32, %ebx
    syscall

when I execute " as exit.s -o exit.o && ld exit.o -o exit -e _start && ./exit"

the return is "Bus error: 10" and the output of "echo $?" is 138

I also tried the example of the correct answer in this question: Process command line in Linux 64 bit

stil get "bus error"...


回答1:


First, you are using old 32-bit Linux kernel calling convention on Mac OS X - this absolutely doesn't work.

Second, syscalls in Mac OS X are structured in a different way - they all have a leading class identifier and a syscall number. The class can be Mach, BSD or something else (see here in the XNU source) and is shifted 24 bits to the left. Normal BSD syscalls have class 2 and thus begin from 0x2000000. Syscalls in class 0 are invalid.

As per §A.2.1 of the SysV AMD64 ABI, also followed by Mac OS X, syscall id (together with its class on XNU!) goes to %rax (or to %eax as the high 32 bits are unused on XNU). The fist argument goes in %rdi. Next goes to %rsi. And so on. %rcx is used by the kernel and its value is destroyed and that's why all functions in libc.dyld save it into %r10 before making syscalls (similarly to the kernel_trap macro from syscall_sw.h).

Third, code sections in Mach-O binaries are called __text and not .text as in Linux ELF and also reside in the __TEXT segment, collectively referred as (__TEXT,__text) (nasm automatically translates .text as appropriate if Mach-O is selected as target object type) - see the Mac OS X ABI Mach-O File Format Reference. Even if you get the assembly instructions right, putting them in the wrong segment/section leads to bus error. You can either use the .section __TEXT,__text directive (see here for directive syntax) or you can also use the (simpler) .text directive, or you can drop it altogether since it is assumed if no -n option was supplied to as (see the manpage of as).

Fourth, the default entry point for the Mach-O ld is called start (although, as you've already figured it out, it can be changed via the -e linker option).

Given all the above you should modify your assembler source to read as follows:

; You could also add one of the following directives for completeness
; .text
; or
; .section __TEXT,__text

.globl start
start:
    movl $0x2000001, %eax
    movl $32, %edi
    syscall

Here it is, working as expected:

$ as -o exit.o exit.s; ld -o exit exit.o
$ ./exit; echo $?
32


来源:https://stackoverflow.com/questions/11179400/basic-assembly-not-working-on-mac-x86-64lion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!