Jah
Jah

Reputation: 1039

using winapi in mingw assembler

I'm tring to compile the following assembly code into shared library (dll)

.extern _GetProcAddress

.global _main
_main:
    CALL _GetProcAddress

using the following commend:

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

but I'm getting the following link error:

`_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)

how can I fix this error and call winapi functions?

Upvotes: 1

Views: 1291

Answers (2)

Alexey Frunze
Alexey Frunze

Reputation: 62106

This code:

// 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

Compiles for me just fine with:

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

And it works by printing this:

Hello World!

It's a slightly cleaned up version of this C code translated by gcc into assembly with the -S switch:

// 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;
}

I got originally this:

        .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

Can't you do the same for the 64-bit case?

Upvotes: 1

JimR
JimR

Reputation: 16153

Link with the import library for the Windows DLL that contains the function you want to call. I believe that symbol is contained in kernel32.dll. You'll need to make an import library and then link with it.

Upvotes: 0

Related Questions