我正在尝试阅读一本关于X86的书,这本书是用VisualC++和Visual的例子编写的。我正试着把这些例子转换成gcc用的。在经历了许多问题之后,我终于得到了至少可以编译的代码,但是现在我得到了分段错误。下面是代码:
集合.s:
.intel_syntax noprefix
.section .text
.globl CalcSum
.type CalcSum, @function
// extern "C" int CalcSum_(int a, int b, int c)
CalcSum:
// Initialize a stack frame pointer
pushq rbp
mov ebp,esp
// Load the argument values
mov eax,[ebp+8]
mov ecx,[ebp+12]
mov edx,[ebp+16]
// Calculate the sum
add eax, ecx
add eax, edx
// Restore the caller's stack frame pointer
popq rbp
ret测试.c:
#include <stdio.h>
extern int CalcSum(int a, int b, int c);
int main() {
int sum = CalcSum(5,6,7);
printf(" result: %d\n",sum);
return 0;
}我正在使用gcc -o execute test.c assembly.s进行编译。如果我将所有32位指令更改为64位(即ebp到rbp),它将运行,但会提供完全随机的输出。有人能指出我在这里做错了什么吗?谢谢!
发布于 2017-06-04 10:59:20
正如评论中所暗示的那样,这是一个电话会议的问题。在Windows和Linux中,32位C函数遵循CDECL calling convention .在64位Linux中,您必须使用System V AMD64 ABI。64-bit calling convention of Windows是不同的。可能会有使用操作系统功能的具体细节。
32位C (GCC):
.intel_syntax noprefix
.section .text
.globl CalcSum
.type CalcSum, @function
// extern "C" int CalcSum_(int a, int b, int c)
CalcSum: // with underscore in Windows: _CalcSum
// Initialize a stack frame pointer
push ebp
mov ebp,esp
// Load the argument values
mov eax,[ebp+8]
mov ecx,[ebp+12]
mov edx,[ebp+16]
// Calculate the sum
add eax, ecx
add eax, edx
// Restore the caller's stack frame pointer
pop ebp
ret64位Linux (GCC):
.intel_syntax noprefix
.section .text
.globl CalcSum
.type CalcSum, @function
// extern "C" int CalcSum_(int a, int b, int c)
CalcSum:
// Load the argument values
mov rax, rdi
add rax, rsi
add rax, rdx
ret64位视窗(明威-GCC):
.intel_syntax noprefix
.section .text
.globl CalcSum
// .type CalcSum, @function
// extern "C" int CalcSum_(int a, int b, int c)
CalcSum:
// Load the argument values
mov rax, rcx
add rax, rdx
add rax, r8
rethttps://stackoverflow.com/questions/44348838
复制相似问题