将程序集NASM代码链接到GCC [英] Link assembly NASM code to GCC

查看:112
本文介绍了将程序集NASM代码链接到GCC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译汇编代码(nasm)时遇到麻烦.

I have a trouble with a compiling assembly code (nasm).

在Linux(elf32)上,使用g ++编译后它不会失败,但是当我尝试使用i686-w64-mingw32-g ++(对于Win32)进行构建时,它失败了.

On Linux (elf32) it not fails after compilation using g++, but when I tried to build it with i686-w64-mingw32-g++ (for Win32) it failed.

我的build.sh脚本:

My build.sh script:

#!/bin/bash

nasm -fwin32 wct.asm
i686-w64-mingw32-g++ -m32 -O2 -Wall -fno-exceptions -ffloat-store -ffast-math -fno-rounding-math -fno-signaling-nans -fcx-limited-range -fno-math-errno -funsafe-math-optimizations -fassociative-math -freciprocal-math -ffinite-math-only -fno-signed-zeros -fno-trapping-math -frounding-math -fsingle-precision-constant -fcx-fortran-rules -fno-rtti -mfpmath=387 -mfancy-math-387 -fno-ident -fmerge-all-constants -mpreferred-stack-boundary=2 -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fno-unroll-loops -fno-math-errno -s main.cpp wct.obj -o wct.exe
strip --strip-unneeded wct.exe

有汇编代码:

   [bits 32]
   section .text
   global wct

   wct:

    mov esi, [esp+4]
    mov edi, esi
    mov ecx, [esp+8]

    @L:
            lodsw
            sub ax, 04141h

            cmp al,0Fh
            jne @F
            dec al
            jmp @E
            @F:
            cmp al,0Eh
            jne @E
            inc al
            @E:

            mov bx, ax
            shr bx, 8

            cmp bl,0Fh
            jne @@F
            dec bl
            jmp @@E
            @@F:
            cmp bl,0Eh
            jne @@E
            inc bl
            @@E:

            shl al, 4
            add ax, bx
            stosb
    loop @L
    ret

main.cpp:

#include <fstream>

using namespace std;

extern "C" int wct(char* buff, int N);

#define N 1024*1024

char buff[N];
ifstream in;
ofstream out;
int size;

int main(int argc, char* argv[]) {

    if ( argc == 1 ) return 0;

    in.open(argv[1], ios_base::in | ios_base::binary);

    if ( argc >= 3 )
        out.open(argv[2], ios_base::out | ios_base::binary);

    if( in.is_open())
    {
        while(!in.eof())
        {
            in.read((char *)&buff, sizeof buff);
            size = in.gcount()/2;
            wct((char *)&buff, size);

            if ( out.is_open())
                out.write((char *)&buff, size);
            else
            {
                out.close();
            }
        }
    }

    in.close();
    out.close();

    return 0;
}

我显然做错了,因为在使用build.sh脚本时,我总是遇到相同的错误:

I am obviously doing something wrong, because of I am always getting the same error while using build.sh script:

/tmp/cc3SD7dA.o:main.cpp:(.text.startup+0x90): undefined reference to `wct'
collect2: error: ld returned 1 exit status

我该如何解决?

推荐答案

在Windows上,GCC编译器期望在外部符号中使用下划线.因此,将asm文件中的所有wct更改为_wct.

On Windows the GCC compiler expects a leading underscore in external symbols. So change all wct in the asm file to _wct.

如果要在Windows和Linux中测试程序,可以全球化"两个连续的标签:wct_wct:

If you want to test the program in Windows and in Linux you can "globalize" two consecutive labels: wct and _wct:

...
global wct
global _wct
...
wct:
_wct:
...

Linux获取不带下划线的wct,Windows附带它.

Linux gets the wct without underscore and Windows gets it with it.

BTW:汇编过程是C函数,必须遵循 CDECL调用约定.该功能可以自由更改寄存器EAXECXEDX(已保存调用者).其他寄存器(EBXESIEDIEBP)必须保持不变.如果该功能需要使用它们,则必须保存并还原它们(已保存被调用者):

BTW: The assembly procedure is a C function and has to follow the CDECL calling convention. The function can freely change the registers EAX, ECX, and EDX (caller saved). The other registers (EBX,ESI,EDI,EBP) have to be returned unchanged. If the function needs to use them, it has to save and restore them (callee saved):

wct:
_wct:

 push esi                ; sp+= 4
 push edi                ; sp+= 4
 push ebx                ; sp+= 4
                        ; ======
                        ; sp+= 12
 mov esi, [esp+16]
 mov edi, esi
 mov ecx, [esp+20]

 ...

 pop ebx
 pop edi
 pop esi
 ret

这篇关于将程序集NASM代码链接到GCC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆