2016-01-31 122 views
0

我想鏈接程序集編譯與C編譯代碼,並且我在鏈接階段得到未定義的引用錯誤。這是我該怎麼做:嵌入程序集生成代碼到C程序使用FASM

[[email protected] test]$ cat ssefuncs.asm 
format ELF64 
EQUAL_ANY  = 0000b 
RANGES   = 0100b 
EQUAL_EACH  = 1000b 
EQUAL_ORDERED  = 1100b 
NEGATIVE_POLARITY = 010000b 
BYTE_MASK = 1000000b 


asm_sse: 
    movntdqa xmm0,[eax] 
    pcmpestri xmm0,[ecx],0x0 

    ret 
[[email protected] test]$ fasm ssefuncs.asm ssefuncs.o 
flat assembler version 1.71.50 (16384 kilobytes memory) 
1 passes, 405 bytes. 
[[email protected] test]$ ls -l ssefuncs.o 
-rw-r--r-- 1 niko niko 405 Jan 31 14:52 ssefuncs.o 
[[email protected] test]$ objdump -M intel -d ssefuncs.o 

ssefuncs.o:  file format elf64-x86-64 


Disassembly of section .flat: 

0000000000000000 <.flat>: 
    0: 67 66 0f 38 2a 00  movntdqa xmm0,XMMWORD PTR [eax] 
    6: 67 66 0f 3a 61 01 00 pcmpestri xmm0,XMMWORD PTR [ecx],0x0 
    d: c3      ret  
[[email protected] test]$ cat stest.c 
void asm_sse(); 

int main() { 

    asm_sse(); 
} 
[[email protected] test]$ gcc -c stest.c 
[[email protected] test]$ gcc -o stest ssefuncs.o stest.o 
stest.o: In function `main': 
stest.c:(.text+0xa): undefined reference to `asm_sse' 
collect2: error: ld returned 1 exit status 
[[email protected] test]$ 

看看ELF文件,它是非常薄,我沒有看到任何符號。 :

[[email protected] test]$ readelf -a ssefuncs.o 
ELF Header: 
    Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
    Class:        ELF64 
    Data:        2's complement, little endian 
    Version:       1 (current) 
    OS/ABI:       UNIX - System V 
    ABI Version:      0 
    Type:        REL (Relocatable file) 
    Machine:       Advanced Micro Devices X86-64 
    Version:       0x1 
    Entry point address:    0x0 
    Start of program headers:   0 (bytes into file) 
    Start of section headers:   149 (bytes into file) 
    Flags:        0x0 
    Size of this header:    64 (bytes) 
    Size of program headers:   0 (bytes) 
    Number of program headers:   0 
    Size of section headers:   64 (bytes) 
    Number of section headers:   4 
    Section header string table index: 3 

Section Headers: 
    [Nr] Name    Type    Address   Offset 
     Size    EntSize   Flags Link Info Align 
    [ 0]     NULL    0000000000000000 00000000 
     0000000000000000 0000000000000000   0  0  0 
    [ 1] .flat    PROGBITS   0000000000000000 00000040 
     000000000000000e 0000000000000000 WAX  0  0  8 
    [ 2] .symtab   SYMTAB   0000000000000000 0000004e 
     0000000000000030 0000000000000018   3  2  8 
    [ 3] .strtab   STRTAB   0000000000000000 0000007e 
     0000000000000017 0000000000000000   0  0  1 
Key to Flags: 
    W (write), A (alloc), X (execute), M (merge), S (strings), l (large) 
    I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) 
    O (extra OS processing required) o (OS specific), p (processor specific) 

There are no section groups in this file. 

There are no program headers in this file. 

There are no relocations in this file. 

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported. 

Symbol table '.symtab' contains 2 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 SECTION LOCAL DEFAULT 1 .flat 

No version information found in this file. 
[[email protected] test]$ 

將FASM生成的彙編代碼嵌入到C程序中的正確方法是什麼?

+0

通常,編譯器通過向C代碼中使用的標識符添加一個或兩個下劃線來創建符號。您是否嘗試在彙編代碼中使用_asm_sse(以下劃線作爲前綴)而不是asm_sse? –

+0

不,我沒有,因爲我的.o文件是完全空的!如果在那裏會有_asm_sse符號,我會用objdump來看它 – Nulik

+0

您應該通過諸如'public asm_sse'之類的指令使'asm_sse'對其他文件中的對象代碼可見。另外,將代碼放在'.text'部分,前面加上'section'.text'代碼可讀的可執行文件'。 –

回答

1

彙編代碼中的子程序名稱通常是指令流內某些位置的簡單標籤。它們不會自動顯示爲與外部目標代碼鏈接。爲了使之成爲可能,應該聲明一個符號public。此外,按照慣例,ELF文件中的代碼位於.text部分。您的彙編文件應如下所示:

format ELF64 
EQUAL_ANY  = 0000b 
RANGES   = 0100b 
EQUAL_EACH  = 1000b 
EQUAL_ORDERED  = 1100b 
NEGATIVE_POLARITY = 010000b 
BYTE_MASK = 1000000b 

section '.text' code readable executable 

asm_sse: 
    movntdqa xmm0,[eax] 
    pcmpestri xmm0,[ecx],0x0 

    ret 

public asm_sse 
-1

這很大程度上取決於所使用的編譯器。例如。 GCC(並通過克隆,clang)具有非常的聯機編寫彙編語言片段的廣泛功能,處理與周圍代碼連接的例程細節(根據需要保存破壞寄存器,將輸入放置在可以使用的位置以及拾取結果結果以及輸入/輸出與給定結果匹配)。這通常是最簡單的方法。

如果上述不是選項,你應該從編寫一個簡短的C程序開始,並將其編譯爲程序集。像cc -g -S somefile.c應該給你一個彙編語言somefile.s-g(或其他調試支持)應該在代碼中包含註釋,從而可以更容易地反向引用C語言。這將允許您對編譯器的結果進行逆向工程,並通過混淆其中的inards組合文件的起點編譯功能。

正如@LaurentH的評論所說,通常編譯器會在生成的彙編語言中使用源碼的名稱來防止與外部符號衝突,例如,預先考慮_甚至某些字符在特定程序集中合法但不在C中,如.$

+0

我需要大會,我正在編寫一個新的輕量級操作系統的核心與大規模並行計算功能 – Nulik