在 Windows 上使用 MinGW 调用 GCC 时如何将 Win32 指定为输出

How to specify Win32 as output when invoking GCC using MinGW on Windows

How to specify Win32 as output when invoking GCC using MinGW on Windows.

下面我贴出了我的源代码。我的 objective 是将汇编与 C 代码连接起来并生成可执行文件。

我开始使用以下 NASM 命令将 add.asm 组装到 Win32:

nasm -f win32 add.asm

那么应该可以使用 C 和目标文件调用 GCC?

gcc -o add add.obj call_asm.c

但是,这会导致链接错误:

C:\Users\nze\AppData\Local\Temp\cckUvRyC.o:call_asm.c:(.text+0x1e): undefined reference to `add'
collect2.exe: error: ld returned 1 exit status

如果我改为使用

编译为 ELF
nasm -f elf add.asm

命令(这次使用ELF文件add.o)

gcc -o add add.o call_asm.c

完美运行。

如何告诉 GCC 我的目标文件是 Win32 格式,以便它在链接之前编译 call_asm.c 到 Win32? (我想这就是问题的核心,请评论我是否正确)。

call_add.c:

#include <stdio.h>

extern int add(int a, int b);

int main()
{
  printf("%d", add(7, 6));
}

add.asm:

    BITS 32
    global _add

_add:
    push ebp
    mov ebp, esp

    mov eax, [ebp+8]
    mov ebx, [ebp+12]
    add eax, ebx

    mov esp, ebp
    pop ebp
    ret

问题并不像您想象的那样。 GCC 正在生成 "win32" 格式(通常称为 PECOFF)目标文件。问题是您的汇编代码没有定义一个部分,这导致 NASM 没有在生成的目标文件中定义符号 _add

如果您添加 SECTION 指令,您的代码将无错误地链接和运行:

    BITS 32

    SECTION .text
    global _add

_add:
    push ebp
    mov ebp, esp

    mov eax, [ebp+8]
    mov ebx, [ebp+12]
    add eax, ebx

    mov esp, ebp
    pop ebp
    ret

告诉 NASM 生成 ELF 目标文件会改变其行为,无论出于何种原因,并导致它在 ELF 目标文件中定义 _add 符号。

只需在标签前添加:

.globl  _add

要将该符号导出到 .DLL 中,您应该在文件末尾添加:

.section .drectve
.ascii " -export:\"add\""

请注意,前导下划线被省略了。