将程序集NASM代码链接到GCC [英] Link assembly NASM code to 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调用约定一个>.该功能可以自由更改寄存器EAX
,ECX
和EDX
(已保存调用者).其他寄存器(EBX
,ESI
,EDI
,EBP
)必须保持不变.如果该功能需要使用它们,则必须保存并还原它们(已保存被调用者):
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屋!