/*********
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
答案 0 :(得分:6)
让程序链接是一件容易的事:
_start
更改为start
$ nasm -f macho exit.asm
$ ld -arch i386 -o exiter exit.o
问题是exit.asm
正在调用i386 Linux exit()
系统调用( EAX = 1),程序将 NOT 退出OS X上预期的零状态。
系统调用是对内核的请求。与exit()
不同,sqrt()
必须向其实现中具有更高权限的软件组件发出请求,因为它终止正在运行的程序。应用无法自行创建或终止进程。系统调用为应用程序提供了一种让内核代表他们执行操作的方法。
进行系统调用是这样的:
1
是系统调用号exit
。0
( EBX 被xor
清除)是系统调用的第一个参数,退出状态。< / LI>
int 80
sycall
ARMv7上的Thumb模式下的svc
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.asm
与:
$ cc -m32 -nostdlib exit.o -o exiter
和
退出-libc.asm 强>
extern exit
global main
main:
push 0
call exit
必须与:
相关联$ cc -m32 exit-libc.o -o exit-libc
试试这个并查看文件大小。
答案 1 :(得分:3)
Mac OS X不使用ELF,因此您需要生成一个Mach-O对象以在该系统上进行链接。在我的机器上nasm
似乎只支持32位输出,因此您在链接时也需要匹配该架构。
我还必须将_start
更改为start
才能将其链接起来。
以下是您的代码的工作示例:
$ cat exit.asm
[SECTION .text]
global start
start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80
$ nasm -f macho exit.asm
$ ld -arch i386 -macosx_version_min 10.7 -o exiter exit.o
$ ./exiter
$ echo $?
236
请注意,该程序可能无法在Mac OS X上执行所需操作,因为它不像Linux那样执行系统调用。
答案 2 :(得分:2)
大多数情况下,当您收到此错误时:
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not
allowed in code signed PIE, but used in _start from hello.o. To fix this
warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
这是因为它正在寻找你的“main()”函数(标签)给我标签“start:”。最好用“ld -e”指定主标签。
-o hello.tmp - outfile
-f macho - specify format
Linux - elf or elf64
Mac OSX - macho
-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
./hello.o - execution
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
请告诉我这是否有帮助!
我在博客上写了如何做到这一点:
http://blog.burrowsapps.com/2013/07/how-to-compile-helloworld-in-intel-x86.html
有关更详细的解释,我在Github上解释说:
答案 3 :(得分:0)
标准mac gcc不会链接elf对象。对于需要坚持使用elf格式并在mac上开发的人来说,你需要一个交叉编译器......
http://crossgcc.rts-software.org/doku.php?id=compiling_for_linux
然后你可以继续进行类似的事情......
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o