C语言 从 c 调用汇编函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13901261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
calling assembly function from c
提问by Ali U.
I'm trying to call an assembly function from c,but i keep getting errors.
我试图从 c 调用一个汇编函数,但我不断收到错误消息。
.text
.globl integrate
.type integrate, @function
integrate:
push %ebp
mov %esp, %ebp
mov #include <stdio.h>
extern int integrate(int from,int to);
void main()
{
printf("%d",integrate(1,10));
}
,%edi
start_loop:
cmp %edi,1024
je loop_exit
mov 8(%ebp),%eax
mov 12(%ebp),%ecx
sub %eax,%ecx
add %edi,%ecx
incl %edi
jmp start_loop
loop_exit:
movl %ebp, %esp
popl %ebp
ret
This is my assembly function,file called integrate.s.
这是我的汇编函数,名为integrate.s 的文件。
function.c:5:6: warning: return type of ‘main' is not ‘int' [-Wmain]
/tmp/cciR63og.o: In function `main':
function.c:(.text+0x19): undefined reference to `integrate'
collect2: ld returned 1 exit status
Heres my c code.
继承人我的c代码。
#include<(file path)/integrate.s>
Whenever i try to compile my code with gcc -Wall function.c -o function,it gives the 'undefined reference to integrate' error.I also tried adding link to the integrate.s file from c,like
每当我尝试使用 gcc -Wall function.c -o 函数编译我的代码时,它都会给出“未定义的集成引用”错误。我还尝试从 c 添加到集成.s 文件的链接,例如
int main()
{
}
but it didnt work as well.Btw what assembly code is doing is not important,for now im just trying to call the function from c successfully.Can anyone help me about solving this problem ?
但它也不起作用。顺便说一句,汇编代码在做什么并不重要,现在我只是想成功地从 c 调用函数。有人能帮我解决这个问题吗?
回答by Jester
I see the following problems with the code:
我看到代码有以下问题:
- calling convention mandates you must preserve the value of
edi cmp %edi,1024is using1024as address and will probably fault. You wantcmp $1024,%edifor comparing with an immediate number- you are reloading
eaxandecxfrom the arguments each iteration so the calculation you perform has no effect - you don't seem to put any sensible return value into
eax(it will return the value offromthat was passed in)
- 调用约定要求您必须保留的值
edi cmp %edi,1024正在1024用作地址并且可能会出错。您想要cmp $1024,%edi与立即数进行比较- 您正在重新加载
eax并ecx从每次迭代的参数中重新加载,因此您执行的计算无效 - 您似乎没有将任何合理的返回值放入
eax(它将返回from传入的值)
The first two points apply even if "what assembly code is doing is not important".
即使“汇编代码在做什么并不重要”,前两点也适用。
回答by Ali U.
warning: return type of ‘main' is not ‘int'
警告:'main' 的返回类型不是 'int'
means that the return type of ‘main' is not ‘int'... Change it to int, then:
意味着 'main' 的返回类型不是 'int'... 将其更改为int,然后:
gcc -o myprog main.c integrate.s
Also, to solve the linker error, invoke GCC as
此外,要解决链接器错误,请调用 GCC 作为
# A program to be called from a C program
# Declaring data that doesn't change
.section .data
string: .ascii "Hello from assembler\n"
length: .quad . - string
# The actual code
.section .text
.global print
.type print, @function #<-Important
print:
mov extern void print(void);
int main(void)
{
print();
return 0;
}
x1,%rax # Move 1(write) into rax
mov ##代码##x1,%rdi # Move 1(fd stdOut) into rdi.
mov $string,%rsi # Move the _location_ of the string into rsi
mov length,%rdx # Move the _length_ of the string into rdx
syscall # Call the kernel
mov %rax,%rdi # Move the number of bytes written to rdi
mov ##代码##x3c,%rax # Move 60(sys_exit) into rax
syscall # Call the kernel
and that should work.
这应该有效。
回答by Olof Nord
Not sure if you have solved this or not, but here is how I have done this.
不确定你是否已经解决了这个问题,但这是我如何做到的。
When compiling make sure to add both files: $gcc main.c print_msg.s -o main
编译时确保添加两个文件: $gcc main.c print_msg.s -o main
To run the assembler file on its own: $as print_msg.s -o print_msg.ofollowed by $ld print_msg.o -e print -o print_msg. Note that this is not required if you only want to run it from your C file.
自行运行汇编程序文件:$as print_msg.s -o print_msg.o后跟$ld print_msg.o -e print -o print_msg. 请注意,如果您只想从 C 文件运行它,则这不是必需的。
The assembler file:
print_msg.s
汇编文件:
print_msg.s
then the C file: main.c
然后是C文件: main.c

