2017-02-10 2 views
0

У меня возникли проблемы с компиляционным кодом сборки (nasm).Ссылка на сборку кода NASM для GCC

В Linux (elf32) это не сбой после компиляции с использованием g ++, но когда я попытался построить его с i686-w64-mingw32-g ++ (для Win32), он не удался.

Мой build.sh сценарий:

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

Я, очевидно, делает что-то не так, из-за I я всегда получаю ту же ошибку при использовании скрипта build.sh:

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

Как я могу это исправить?

+0

@ smac89: В * wct.obj *, объектный код, что NASM листинга компилируется. Я думаю, что существует несоответствие между использованием декодерированного и украшенного символа. Либо NASM управляет им, либо GCC. В любом случае, для этого также нужна конвенция о вызове. – IInspectable

+0

@Inpectable, как я могу назвать соглашение? –

+1

Обратитесь к своему [руководству по компиляции] (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html). – IInspectable

ответ

0

В Windows компилятор GCC ожидает, что ведущее подчеркивание внешних символов. Поэтому измените все wct в asm-файле на _wct.

Если вы хотите протестировать программу в Windows, и в Linux вы можете «глобализацию» два последовательных метки: wct и _wct:

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

Linux Получает wct без подчеркивания и Windows, получает его с ним.

BTW: Процедура сборки является функцией C и должна соответствовать CDECL calling convention. Функция может свободно изменять регистры EAX, ECX и EDX (звонок сохраняется). Остальные регистры (EBX, ESI, EDI, EBP) должны быть возвращены без изменений. Если функция должна использовать их, он должен сохранять и восстанавливать их (вызываемый сохранено):

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 
Смежные вопросы