[英]embed assembly produced code into C program using FASM
I am trying to link assembly-compiled with c-compiled code, and I get undefined reference error during linking phase. 我试图用C编译的代码链接汇编编译的代码,并且在链接阶段出现未定义的引用错误。 This is how i do it:
这是我的方法:
[niko@dev1 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
[niko@dev1 test]$ fasm ssefuncs.asm ssefuncs.o
flat assembler version 1.71.50 (16384 kilobytes memory)
1 passes, 405 bytes.
[niko@dev1 test]$ ls -l ssefuncs.o
-rw-r--r-- 1 niko niko 405 Jan 31 14:52 ssefuncs.o
[niko@dev1 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
[niko@dev1 test]$ cat stest.c
void asm_sse();
int main() {
asm_sse();
}
[niko@dev1 test]$ gcc -c stest.c
[niko@dev1 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
[niko@dev1 test]$
Looking at the ELF file, it is very thin and I don't see any symbols. 看一下ELF文件,它很薄,我看不到任何符号。 :
:
[niko@dev1 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.
[niko@dev1 test]$
What is the correct way to embed FASM produced assembly code into a C program? 将FASM产生的汇编代码嵌入C程序的正确方法是什么?
Subroutine names in assembly code are usually simply labels for certain positions within the instruction stream. 汇编代码中的子例程名称通常只是指令流中某些位置的标签。 They are not automatically made visible for linking with external object code.
对于与外部目标代码的链接,不会自动使它们可见。 To make it possible, a symbol should be declared
public
. 为了使之成为可能,应将符号声明为
public
。 Also, by convention the code in ELF files resides in the .text
section. 同样,按照惯例,ELF文件中的代码位于
.text
节中。 Your assembly file should look like this: 您的程序集文件应如下所示:
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
It much depends on the compiler used. 这很大程度上取决于所使用的编译器。 Eg GCC (and by cloning, clang) has a very extensive facility for writing assembly language snippets in-line, handling the routine details of interfacing with the surrounding code (saving clobbered registers as needed, placing inputs where they can be used and picking up results, and matching inputs/outputs with what is given).
例如,GCC(通过克隆,clang)具有非常广泛的功能,可以在线编写汇编语言片段,处理与周围代码交互的例行细节(按需保存损坏的寄存器,将输入放置在可以使用的位置并进行提取)结果,并将输入/输出与给定的值进行匹配)。 This is usually the easiest way to go.
这通常是最简单的方法。
If the above isn't an option, you should start by writing a short C program, and compile it to assembly. 如果没有上述选择,则应从编写简短的C程序开始,然后将其编译为汇编程序。 Something like
cc -g -S somefile.c
should give you a somefile.s
with assembly language. 诸如
cc -g -S somefile.c
类的东西应该为您提供带有汇编语言的somefile.s
。 The -g
(or other debugging enablement) should include comments in the code, allowing easier backreference to C. This will allow you to reverse engineer the compiler's result, and serve as a starting point for a standalone assembly file by messing with the inards of the compiled functions. -g
(或其他调试启用)应在代码中包含注释,以便更轻松地向C进行反向引用。这将允许您对工程结果进行反向工程,并通过弄乱了inard的内容作为独立程序集文件的起点。编译的函数。
As the comment by @LaurentH says, often compilers mangle names of source symbols in generated assembly language to prevent clashing with outside symbols, by eg prepending _
or even some characters legal in the specific assembly but not in C, like .
就像@LaurentH的评论所说,编译器经常以生成的汇编语言来修饰源符号的名称,以防止与外部符号冲突,例如,在特定的汇编中添加
_
甚至某些合法的字符,例如在C中则不允许.
or $
. 或
$
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.