2013-02-10 185 views
1

我想用gcc創建一個可執行文件。我有兩個文件virtualstack.c(由下面的C代碼組成)和stack.s,它由用AT & T語法編寫的intel x86彙編代碼(見C代碼下面)組成。我的命令行命令是gcc -c virtualstack.c -s stack.s,但我得到兩個錯誤(stack.s中的第3行) - missing symbol name in directiveno such instruction _stack_create。我以爲我已經正確地聲明瞭C語言中的函數,前綴爲下劃線(_)。我會非常感謝任何意見。gcc彙編和彙編

C代碼:

#include <stdio.h> 
#include <stdlib.h> 

extern void stack_create(void); 

int main(void) 
{ 
stack_create(); 

return 0; 
} 

彙編代碼:

.global _stack_create 
    .type, @function 

_stack_create 
pushl %ebp 
movl $5, %esp 
movl %esp, ebp 
movl $21, %edx 
pushl %edx 
+1

第二個'_stack_create'後面需要冒號。我不知道'.type'是否正確,但不需要。順便說一句,把5移到'esp'就是在問問題。 – 2013-02-10 11:31:06

+0

@alexey frunze。謝謝你:)現在我對結腸感到愚蠢。我應該看到那一個。沒有.type編譯。我仍然需要看看它是否可執行。也感謝esp警告。 – stian 2013-02-10 11:45:02

+0

好。我刪除了.type,@function。我發現gcc創建獨立的對象文件。我試着寫gcc -o vs virtualstack.c -s stack.s。我相信應該創建一個vsout文件(可執行文件)。然後我得到未定義的參考在main()中的stack_create - 有什麼想法爲什麼? – stian 2013-02-10 12:05:05

回答

2

我將試圖解釋你的方法如何調查此類案件。

1)編譯器爲你工作總是個好主意。所以,讓我們開始與代碼(可以稱之爲assemble.c):

#include <stdio.h> 
    #include <stdlib.h> 

    /* stub stuff */ 
    void __attribute__ ((noinline)) 
    stack_create(void) { } 

    int 
    main(void) 
    { 
     stack_create(); 
     return 0; 
    } 

現在編譯它gcc -S -g0 assemble.c成彙編。 stack_create功能組裝到(您的結果可能會有所不同,所以請自行按照我的指示):

.text 
    .globl stack_create 
    .type stack_create, @function 
stack_create: 
    pushq %rbp 
    movq %rsp, %rbp 
    popq %rbp 
    ret 
    .size stack_create, .-stack_create 

2)現在,所有你需要的是利用這個模板,並與你的東西填滿它:

.text 
    .globl stack_create 
    .type stack_create, @function 
stack_create: 
    pushq %rbp 
    movq %rsp, %rbp 

    ;; Go and put your favorite stuff here! 
    pushl %ebp 
    movl $5, %esp 
    movl %esp, ebp 
    movl $21, %edx 
    pushl %edx 
    ... etc ... 

    popq %rbp 
    ret 
    .size stack_create, .-stack_create 

並且當然可以將它分開.s文件,比如stack.s。

3)現在讓我們一起編譯。從assemble.c中刪除存根的東西,並編譯一切爲:

gcc assemble.c stack.s 

我沒有錯誤。我相信你也不會有任何錯誤。

主要教訓:千萬不要嘗試在彙編程序中編寫像段,函數標籤等細節。編譯器會更好地知道如何去做。改用他的知識。