/*********
exit.asm
*/

[SECTION .text]

global _start


_start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80

//****************************

首先,我使用nasm -f elf exit.asm生成目标文件。

然后在Mac OS X 10.7上运行以下“ld”命令,它具有以下输出和警告,我尝试在32位linux机器上运行它,一切顺利,
您能否解释一下为什么链接器无法在Mac上运行?

谢谢!
Alfred says: ld -o exiter exit.o
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specified, assuming 10.7
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45      0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the   architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
  "start", referenced from:
    implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64

指定拱形和版本后,我得到:
Alfred says: ld -arch x86_64 -macosx_version_min 10.7 -o exiter exit.o
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45     0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the   architecture being linked (x86_64): exit.o
 Undefined symbols for architecture x86_64:
 "start", referenced from:
    implicit entry/start for main executable
 ld: symbol(s) not found for architecture x86_64

最佳答案

使程序链接起来很容易:

  • _start更改为start
  • $ nasm -f macho exit.asm
  • $ ld -arch i386 -o exiter exit.o

  • 问题在于exit.asm正在调用i386 Linux exit()系统调用( EAX = 1),并且该程序不会以OS X上预期的零状态退出。

    系统调用

    系统调用是对内核的请求。 exit()sqrt()不同,由于它终止正在运行的程序,因此必须向其实现中具有更高特权的软件组件发出请求。应用程序无法自行创建或终止进程。系统调用提供了一种方法,使应用程序可以要求内核代表它们执行操作。

    进行系统调用是这样的:
  • Apps通过将数据放入CPU寄存器(或寄存器指向的内存)中来描述他们想要执行的操作。
  • EAX 中的1值是exit的系统调用号码。
  • EBX 中的0值(xor清除了 EBX )是系统调用的第一个参数,即退出状态。
  • Apps发出一条指令,使控制权转移到内核,例如

    i386上的
  • int 80
  • x86-64上的
  • sycall
  • 在ARMv7上的Thumb模式下
  • svc
  • 内核检查请求并决定执行还是拒绝它。
  • 内核将控制权返回到应用程序,并将返回值放在约定的位置,例如 i386上的EAX

  • Linux和OS X都为C程序提供了void exit(int)函数,但对于如何向内核描述此请求的细节不同意。 exit.asm中的代码与_exit()libc函数的实现处于同一级别。

    即使在运行Linux的不同体系结构之间,系统调用号和调用约定也有所不同。例如在x86-64 Linux上,exit(0)的发出更为常见,如下所示:
    xor rdi, rdi
    mov al, 60
    syscall
    

    您可以通过在_exit中拆卸/lib64/libc.so.6来查看此内容。

    我们不能只从libc调用exit()吗?

    你可以。但是您必须将程序与libc链接。将上面的exit.asm与以下链接之间的区别是:
    $ cc -m32 -nostdlib exit.o -o exiter
    



    exit-libc.asm
    extern exit
    global main
    main:
    push 0
    call exit
    

    该链接必须与:
    $ cc -m32 exit-libc.o -o exit-libc
    

    试试这个,看看文件的大小。

    关于无法使用ld链接目标文件-Mac OS X,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16801432/

    10-11 21:57
    查看更多