由于某种原因,Mov 和 add 什么都不做
Mov and add are doing nothing for some reason
我从我的大学教授那里得到了这段代码,所以我相当确定代码有效,但对我来说输出总是 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。
这部分汇编语言...
mov eax, edi
add eax, esi
... 是将前两个 int
参数添加到函数和 return 结果的正确方法,if 前两个 int
函数的参数在寄存器 edi
和 esi
中。在 x86 Linux 上,当且仅当程序是使用“64 位 ABI”编译时,这才是正确的,这可能是也可能不是您的 Ubuntu 虚拟机默认执行的操作。据我所知,无论 ABI 是什么,Windows 都不是真的。
然而,Linux 64 位 ABI 的使用与汇编语言的其余部分不一致:特别是,在 Linux(所有变体)上,一个名为 func
对应于名为 func
的汇编语言过程,而不是 _func
。但这应该会导致您的程序无法 link(gcc
命令会产生一条错误消息说 "undefined reference to `func'"),而不是产生不正确的输出。
我建议你回到给你汇编代码的教授那里,问问他们应该使用什么操作系统和 ABI,以及如何使其适应你可以方便访问的计算机.
(您之前可能没有遇到过术语 "ABI"。它代表应用程序二进制接口,它是关于过程调用等低级细节如何工作的一堆规则。例如, Linux 使用的 "x86-64 ELF ABI" 表示函数调用的前两个整数参数在 CALL 指令之前放置在 DI 和 SI 寄存器中(按此顺序),并且一个整数 return 值将在 returns 之后在 AX 中找到。但是 x86-64 Windows ABI 表示函数的前两个整数参数被放置在其他两个寄存器中——我不记得是哪两个——而 x86-32 ELF ABI 说它们进入堆栈。每个人都同意整数 return 值出现在 AX 中。)
我从我的大学教授那里得到了这段代码,所以我相当确定代码有效,但对我来说输出总是 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。
这部分汇编语言...
mov eax, edi
add eax, esi
... 是将前两个 int
参数添加到函数和 return 结果的正确方法,if 前两个 int
函数的参数在寄存器 edi
和 esi
中。在 x86 Linux 上,当且仅当程序是使用“64 位 ABI”编译时,这才是正确的,这可能是也可能不是您的 Ubuntu 虚拟机默认执行的操作。据我所知,无论 ABI 是什么,Windows 都不是真的。
然而,Linux 64 位 ABI 的使用与汇编语言的其余部分不一致:特别是,在 Linux(所有变体)上,一个名为 func
对应于名为 func
的汇编语言过程,而不是 _func
。但这应该会导致您的程序无法 link(gcc
命令会产生一条错误消息说 "undefined reference to `func'"),而不是产生不正确的输出。
我建议你回到给你汇编代码的教授那里,问问他们应该使用什么操作系统和 ABI,以及如何使其适应你可以方便访问的计算机.
(您之前可能没有遇到过术语 "ABI"。它代表应用程序二进制接口,它是关于过程调用等低级细节如何工作的一堆规则。例如, Linux 使用的 "x86-64 ELF ABI" 表示函数调用的前两个整数参数在 CALL 指令之前放置在 DI 和 SI 寄存器中(按此顺序),并且一个整数 return 值将在 returns 之后在 AX 中找到。但是 x86-64 Windows ABI 表示函数的前两个整数参数被放置在其他两个寄存器中——我不记得是哪两个——而 x86-32 ELF ABI 说它们进入堆栈。每个人都同意整数 return 值出现在 AX 中。)