2011-08-05 72 views
9



我想運行一個基本的程序集文件使用64位Mac OS X的獅子,使用默認情況下與Xcode安裝的nasm和ld。無法鏈接彙編文件在Mac OS X中使用ld

我寫了一個程序集文件,它打印出一個字符,然後用它來建立使用nasm。

nasm -f elf -o program.o main.asm

然而,當我去給它使用ld鏈接時,出現了不少錯誤/警告:

ld -o program program.o

ld: warning: -arch not specified 
ld: warning: -macosx_version_min not specificed, assuming 10.7 
ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64) 
ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib 
ld: entry point (start) undefined. Usually in crt1.o for inferred architecture x86_64 

所以,我試圖糾正幾個這些問題,並沒有得到。

這裏是我試過的事情之一:

ld -arch i386 -e _start -o program program.o

我本以爲這工作,但我錯了。

如何使目標文件成爲nasm和ld將會同意的兼容體系結構?

還有,你怎麼會在程序中定義的入口點(現在我使用global _start.section text,高於_start,這似乎並沒有多大作用。)

我是有點困惑,你如何成功地將一個目標文件鏈接到一個使用ld的二進制文件,我想我只是缺少一些代碼(或者對nasm或ld的參數),這將使他們同意。

任何幫助表示讚賞。

+0

您是否嘗試過使用gcc而不是ld進行鏈接?它通常容易得多,您可以使用C運行時和標準庫(例如,以'main'作爲入口點)。另一個嘗試是使用'mach'目標文件格式而不是'elf'。 – user786653

回答

2

只需讓gcc爲您完成繁重的工作,而不是直接嘗試直接驅動ld(例如,

$ gcc -m32 program.o -o program 
5

好吧,看看你的示例我假設你使用了一個通用的nasm或linux彙編教程。
您需要處理的第一件事是由nasm創建的二進制格式。
您的文章中指出:

ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64) 

多數民衆贊成在-f精靈參數,它會告訴你想有一個32位的ELF對象(這將是Linux的例如情況)NASM的結果。但是既然你在OSX上,你想要的是一個Mach-O對象。

嘗試以下操作:

nasm -f macho64 -o program.o main.asm 
gcc -o program program.o 

或者,如果你wan't創建一個32位二進制:

nasm -f macho32 -o program.o main.asm 
gcc -m32 -o program program.o 

關於_start符號 - 如果你wan't到創建一個簡單的程序,將能夠 使用所提供的libc系統的功能,那麼你不應該使用_start at al。 它的默認入口點LD將尋找和normaly它在你的libc/libSystem中提供。

我建議你嘗試的東西來代替_start在你的代碼像「_main」 和像上面狀態的例子聯繫起來。

爲NASM一個通用的基於libc的組裝模板看起來是這樣的:

;--------------------------------------------------- 
.section text 
;--------------------------------------------------- 
use32    ; use64 if you create 64bit code 
global _main  ; export the symbol so ld can find it 

_main: 
    push ebp 
    mov ebp, esp ; create a basic stack frame 

    [your code here] 

    pop ebp  ; restore original stack 
    mov eax, 0 ; store the return code for main in eax 
    ret   ; exit the program 

除了這個我應該指出,任何呼叫的你OSX確實需要使用對齊的堆棧幀或您的代碼只會崩潰。
有上了一些很好的教程有太多 - 嘗試搜索OSX裝配指南。

5

您需要使用global startstart:,沒有下劃線。此外,你不應該使用elf作爲拱門。這裏是一個bash腳本我用來組裝在Mac OS X我的x86-64 NASM方案:

#!/bin/bash 

if [[ -n "$1" && -f "$1" ]]; then 
    filename="$1" 
    base="${filename%%.*}" 
    ext="${filename##*.}" 

    nasm -f macho64 -Ox "$filename" \ 
    && ld -macosx_version_min 10.7 "${base}.o" -o "$base" 
fi 

如果你有一個名爲foo.s文件,該腳本將首先運行

nasm -f macho64 -Ox foo.s 

,這將創造foo.o。該-Ox標誌使NASM做跳躍(即造成其短,近或遠),這樣就不必自己做一些額外的優化。我使用的是x86-64,所以我的代碼是64位的,但是它看起來像是在試圖組裝32位。在這種情況下,您可以使用-f macho32。有關有效輸出格式的列表,請參見nasm -hf。現在

,目標文件將被鏈接:

ld -macosx_version_min 10.7 foo.o -o foo 

我已經設置了-macosx_version_min選項安靜下來NASM,防止警告。您不必將其設置爲Lion(10.7)。這將創建一個名爲foo的可執行文件。運氣好的話,輸入./foo並點擊返回應該運行你的程序。

在關於ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib警告,我得到的,每次過,我不知道爲什麼,但一切似乎都很好,當我運行可執行文件。