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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:45:41  来源:igfitidea点击:

calling assembly function from c

cassemblyx86inline-assembly

提问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 using 1024as address and will probably fault. You want cmp $1024,%edifor comparing with an immediate number
  • you are reloading eaxand ecxfrom 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 of fromthat was passed in)
  • 调用约定要求您必须保留的值 edi
  • cmp %edi,1024正在1024用作地址并且可能会出错。您想要cmp $1024,%edi与立即数进行比较
  • 您正在重新加载eaxecx从每次迭代的参数中重新加载,因此您执行的计算无效
  • 您似乎没有将任何合理的返回值放入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

##代码##