X86装配问题

时间:2017-06-03 21:47:22

标签: c gcc assembly

我正在尝试通过使用Visual C ++和Visual Studio中的示例编写的X86上的一本书。我正在尝试将这些示例转换为与gcc一起使用。经过一系列的问题,我终于完成了至少可以编译的代码,但现在我得到了段错误。这是代码:

assembly.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

test.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位(即ebprbp),它将运行但提供完全随机的输出。谁能指出我在这里做错了什么?谢谢!

1 个答案:

答案 0 :(得分:1)

正如评论中所暗示的那样,这是一个召集会议的问题。 32位C函数遵循Windows和Linux中的CDECL calling convention。在64位Linux中,您必须使用System V AMD64 ABI64-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
    ret

64位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

    ret

64位Windows(MingW-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

    ret