2017-04-27 100 views
-1

我面對我的工作是開發Hadoop的源代碼中的問題。我需要在asm庫中使用函數。給出API,例如: uint32_t func(uint32_t var1,const char var2,uint64_t var3)。 如何使用此函數並獲取C程序中的返回值?我總是得到undefined reference to "a function name(which I want to use asm api)"。 是否有一些典型的聲明我必須添加在C或其他東西?如何使用asm函數用C

似乎很容易爲專業的C程序員,沒有值得質疑。但我是一位Java程序員,對ASM和C真的不熟悉。我希望能夠有效地得到答案。謝謝。

+2

該API給出如何?有函數原型的頭文件嗎?你包括它嗎? asm庫是否添加到項目中以便它被鏈接? – Lundin

+1

「給出了API?」如果您有一個頭文件,請確保將它包含在.c文件中,並確保您的庫已添加到項目中並且已鏈接到項目。也許這個線程會幫助你:http://stackoverflow.com/questions/24991944/linking-c-with-nasm – 23ars

+0

你編程的操作系統和體系結構是什麼?你能告訴我們相關的代碼嗎? – fuz

回答

1

讓我們GNU例如,gcc和本身告訴我們,如果我們聲明爲靜態函數那麼它是不是提供給其他.c文件的語言。在gnu中,彙編語言和彙編語言是由彙編語言定義的,而不是某種通用語言標準,除非聲明爲全局語言,否則標籤是本地的。

hello: 
.globl there 
there: 

我們將無法鏈接到hello,但我們可以鏈接到那裏。

然後,你需要知道調用約定,你可以查找並閱讀和/或做實驗來弄明白。即使你讀了它,以確保您使用的是符合您正在閱讀的一個編譯器,你還是應該做實驗,你正在使用的編譯器將符合任何標準它使用,而不是一個你希望它使用,這樣會讓你的ASM比賽......

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return((a<<2)+b); 
} 

00000000 <fun>: 
    0: e0810100 add r0, r1, r0, lsl #2 
    4: e12fff1e bx lr 

這是手臂,在這種情況下的參數在R0,R1,R2,R3它們是否適合通過,然後如果你有更多的話,請去堆棧。如果它適合返回值在r0中,則有很多例外。你可以在函數中銷燬r0-r3,但必須保留r4(可能有一個例外)。所以在這種情況下,r0左移2並加到r1,所以r0是a,r1必須是b,並且返回值在本實驗中爲r0。

00000000 <fun>: 
    0: 0f 5f   rla r15  
    2: 0f 5f   rla r15  
    4: 0f 5e   add r14, r15 
    6: 30 41   ret 

使用其他指令集R15似乎是一個和R14 B和答案R15

00000000 <_fun>: 
    0: 1166   mov r5, -(sp) 
    2: 1185   mov sp, r5 
    4: 1d40 0004  mov 4(r5), r0 
    8: 0cc0   asl r0 
    a: 0cc0   asl r0 
    c: 6d40 0006  add 6(r5), r0 
    10: 1585   mov (sp)+, r5 
    12: 0087   rts pc 

返回,另一個指令集使用堆棧

我建議你原型您的ASM函數,你想從C調用C,然後編譯它,並從那裏反彙編並建立你的模塊。實際組裝它比試圖使用內聯彙編容易得多,這是一個高級主題,並且非常依賴編譯器,如果不使用內聯彙編,則它有更好的工作機會。

因此,例如,我想借此所學到的知識和創造

.globl myfun 
myfun: 
    add r0,r1,r0, lsl #2 
    bx lr 

然後我可以組裝這一點,在任何人要調用myfun兩個參數聯繫起來。或者我可以用這些知識用這兩個參數來做其他事情來創建返回值。

+0

哇!真的很好的建議,加入asm和C在一起。我會進一步思考。你說內聯彙編是一個高級主題和依賴編譯器。你的意思是在C中使用原型asm可以避免編譯器差異的問題嗎? – AnyangWang

+0

爲了讓你的內聯程序集不與編譯器生成的程序集衝突,特別註冊你想要使用的,或者更糟的是,如果你想將C中的變量與程序集連接起來,你必須學習該編譯器關於如何執行此操作的語法,不僅僅是程序集,它還是其他編譯器的東西,它不是永遠不會被使用,但不常用,因此文檔和/或外部人員數量較少。如果你想學習asm,學習asm,那麼學習特定的編譯器東西,C也學習C然後學習編譯器特定的東西...或者... –

+0

或...從來不打擾編譯器特定的東西,過着幸福的生活... –

0

如果您需要調用C或彙編從Java,使用JNI或其替代品。要調用匯編,請創建一個小的C封裝函數來模擬程序集應該執行的操作,然後編譯它並使用Java程序進行調試(驗證是否可以傳遞參數,獲取返回值)。

當這個工作,注重從調用C.這實際裝配真的取決於「ASM庫」,它應該有文檔,如何把它從C

調用

注意裝配庫通常需要一定的CPU建築。例如,如果該庫適用於英特爾32位,則不能從Java VM調用64位ARM(至少,這不容易)。

+0

是的,我的目標彙編庫是英特爾的。我成功構建它,並且我需要的功能可以在xxx.so文件中找到。就像你說的,我需要的只是一個C包裝函數來連接java和程序集。 C代碼已準備就緒。但是,我確切地知道如何在C和彙編之間進行引用。我覺得它只需要在C代碼中進行一些聲明。你能否給我一些線索? – AnyangWang

+0

英特爾庫應該有一個體面的文檔和一些例子。嘗試找到它。通常他們應該有一些C包含文件又名「.h文件」。 – ddbug