我从我的大学教授那里得到了这段代码,所以我很确定代码是有效的,但是对我来说输出总是0。
我在Windows和虚拟Ubuntu上都试过了,但还是一样。
我正在使用mingw编译:
gcc试验c试验s
这是C代码:

#include <stdio.h>

int func(int a, int b);

int main()
{
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", func(a, b));
    return 0;
}

这是大会:
.intel_syntax noprefix

.text

    .globl _func

_func:

    enter 0,0

    mov eax, edi
    add eax, esi
    leave
    ret

对于输入2和3,它应该输出5,但总是0。

最佳答案

汇编语言的这一部分。。。

    mov eax, edi
    add eax, esi

... 如果函数的前两个int参数位于寄存器intedi中,则是将前两个esi参数添加到函数并返回结果的正确方法之一。在x86 Linux上,只有当程序是用“64位ABI”编译的时候,这才是真的,默认情况下,这可能是也可能不是你的Ubuntu虚拟机所做的。据我所知,这在窗户上是不可能的,不管ABI是什么。
然而,Linux 64位ABI的使用与汇编语言的其他部分不一致:特别是在Linux(所有种类)上,名为func的C函数对应于名为func的汇编语言过程,而不是_func。但这应该会导致程序无法链接(gcc命令将生成一条错误消息,说明“未定义对'func'的引用”),而不是生成不正确的输出。
我建议你回到给你汇编代码的教授那里,问他们应该使用什么操作系统和ABI,以及如何使它适应你方便使用的计算机。
(你以前可能没有遇到过“ABI”这个词。它代表应用程序二进制接口,它是一系列规则,用于说明过程调用之类的底层细节是如何工作的。例如,Linux使用的“x86-64 ELF ABI”表示,函数调用的前两个整型参数放在调用指令之前的DI和SI寄存器中(按此顺序排列),返回后在AX中找到整型返回值。但是x86-64 Windows ABI说,函数的前两个整数参数放在其他两个寄存器中——我不记得是哪两个——而x86-32 ELF ABI说它们在堆栈上。不过,每个人都同意AX中出现的整数返回值。)

关于c - Mov和Add由于某种原因无所事事,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54375072/

10-15 01:59