1

我正在尝试将以下汇编代码编译到共享库(dll)中

.extern _GetProcAddress

.global _main
_main:
    CALL _GetProcAddress

使用以下推荐:

i686-w64-mingw32-gcc -shared -o file.dll file.S

但我收到以下链接错误:

`_GetProcAddress' referenced in section `.text' of /tmp/ccamwU4N.o: defined in discarded section `.text' of /usr/lib/gcc/i686-w64-mingw32/4.6/../../../../i686-w64-mingw32/lib/../lib/libkernel32.a(dxprbs00553.o)

如何修复此错误并调用 winapi 函数?

4

2 回答 2

1

这段代码:

// file: winapi0.s
.extern  ___main
.extern  _GetStdHandle@4
.extern  _WriteConsoleA@20

        .data
_text:
        .ascii "Hello World!\12\0"

        .section .text.startup,"x"
        .p2align 2,,3

.globl  _main
_main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $52, %esp
        call    ___main
        movl    $-11, (%esp)
        call    _GetStdHandle@4
        pushl   %edx
        movl    $0, 16(%esp)
        leal    -12(%ebp), %edx
        movl    %edx, 12(%esp)
        movl    $14, 8(%esp)
        movl    $_text, 4(%esp)
        movl    %eax, (%esp)
        call    _WriteConsoleA@20
        subl    $20, %esp
        xorl    %eax, %eax
        movl    -4(%ebp), %ecx
        leave
        leal    -4(%ecx), %esp
        ret

为我编译就好了:

gcc -Wall -O2 winapi0.s -o winapi0.exe

它通过打印这个来工作:

Hello World!

-S这是由 gcc 翻译成带有开关的汇编的这个 C 代码的稍微清理的版本:

// file: winapi.c
#include <windows.h>
#include <tchar.h>

TCHAR text[] = _T("Hello World!\n");

int main(void)
{
  DWORD err;

  WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
               text,
               sizeof(text) / sizeof(text[0]),
               &err,
               NULL);

  return 0;
}

我最初得到这个:

        .file   "winapi.c"
        .def    ___main;        .scl    2;      .type   32;     .endef
        .section        .text.startup,"x"
        .p2align 2,,3
        .globl  _main
        .def    _main;  .scl    2;      .type   32;     .endef
_main:
LFB14:
        .cfi_startproc
        leal    4(%esp), %ecx
        .cfi_def_cfa 1, 0
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        .cfi_escape 0x10,0x5,0x2,0x75,0
        pushl   %ecx
        .cfi_escape 0xf,0x3,0x75,0x7c,0x6
        subl    $52, %esp
        call    ___main
        movl    $-11, (%esp)
        call    _GetStdHandle@4
        pushl   %edx
        movl    $0, 16(%esp)
        leal    -12(%ebp), %edx
        movl    %edx, 12(%esp)
        movl    $14, 8(%esp)
        movl    $_text, 4(%esp)
        movl    %eax, (%esp)
        call    _WriteConsoleA@20
        subl    $20, %esp
        xorl    %eax, %eax
        movl    -4(%ebp), %ecx
        .cfi_def_cfa 1, 0
        leave
        leal    -4(%ecx), %esp
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
LFE14:
        .globl  _text
        .data
_text:
        .ascii "Hello World!\12\0"
        .def    _GetStdHandle@4;        .scl    2;      .type   32;     .endef
        .def    _WriteConsoleA@20;      .scl    2;      .type   32;     .endef

你不能对 64 位的情况做同样的事情吗?

于 2012-10-06T07:08:33.073 回答
0

与包含您要调用的函数的 Windows DLL 的导入库链接。我相信该符号包含在 kernel32.dll 中。您需要创建一个导入库,然后与之链接。

于 2012-10-06T05:13:47.863 回答