c - X86 汇编问题

标签 c gcc assembly

我正在尝试阅读一本使用 Visual C++ 和 Visual Studio 中的示例编写的关于 X86 的书。我正在尝试将示例转换为与 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 位(即 ebprbp),它将运行但给出完全随机的输出。谁能指出我在这里做错了什么?谢谢!

最佳答案

正如评论中所暗示的,这是调用约定的问题。 32 位 C 函数遵循 CDECL calling convention在 Windows 和 Linux 中。在 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
    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

关于c - X86 汇编问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44348838/

相关文章:

将 Swift 字符串数组转换为 c 字符**

c - 在函数声明中将指针声明为参数的 3 种方法是什么?

c - 如何用 C 语言从字符串中解析 IP 地址?

比较代码实现,GCC,if/else->continue

c - 警告 : incompatible implicit declaration of built-in function 'function xyz' [enabled by default]

c++ - g++ 对 -Ofast 做了哪些额外的优化?

c++ - 在 64 位 debian 上编译 GCC 的 CodeViz 补丁

assembly - bootsect.s : How com that we can access the next line after moving the code itself away?

c - 在汇编中声明一个字符串

c 库 x86/x64 汇编程序