我从大学教授那里获得了这段代码,因此我相当确定代码可以工作,但是对我来说输出始终为0。
我在Windows和虚拟Ubuntu计算机上尝试过,但还是一样。
我正在使用mingw进行编译:
gcc test.c test.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。
答案 0 :(得分:3)
这部分汇编语言...
mov eax, edi
add eax, esi
...是将前两个int
参数添加到函数并返回结果的正确方法,如果前两个int
参数是函数在寄存器edi
和esi
中。在x86 Linux上,当且仅当程序使用“ 64位ABI”编译时,这才是正确的,默认情况下,这可能会也可能不是您的Ubuntu虚拟机执行的操作。据我所知,无论ABI如何,在Windows上都是如此。
但是,Linux 64位ABI的使用与其余汇编语言不一致:尤其是在Linux(所有变体)上,名为func
的C函数对应于名为的汇编语言过程func
,而不是_func
。但这应该导致您的程序无法链接(gcc
命令将产生一条错误消息,提示“未定义对'func'的引用”),而不产生错误的输出。
我建议您回到教授汇编代码的教授那里,询问他们应该使用哪种操作系统和ABI,以及如何使其适应您方便使用的计算机。< / p>
(您以前可能没有遇到过“ ABI”一词。它代表应用程序二进制接口,它是一堆规则,用于诸如过程调用之类的底层细节的工作方式。例如,“ x86- Linux使用的“ 64 ELF ABI”表示,函数调用的前两个整数参数(按此顺序)放在CALL指令之前的DI和SI寄存器中,并将在AX中找到一个整数返回值但是x86-64 Windows ABI表示,函数的前两个整数参数放在另外两个寄存器中(我不记得是哪两个),而x86- 32 ELF ABI表示它们进入堆栈。每个人都同意AX中出现的整数返回值。)