[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Wstawki asemblerowe dla GCC........problem z dostępem do przestrzeni I/O z poziomu asemblera GCC dla Debiana



Witam,
Mam problem z używaniem poleceń asemblera In i Out dla maszyn x86. Używam Debiana Etch oraz GCC (ver. dla Debiana 4:4.0.2-2). Moim zadaniem jest napisać sterowniki obsługi łacza szeregowego COM1 dla systemu pracujacego na Debianie. Nie moge korzystać z funcji zawartych w biosie, tylko z danych zawartych w odpowiednich rejestrach(implementacja najblizej sprzetu jak sie tylko da). Z tego też względu potrzebuję funcji, które umożliwią mi odczyt danych z konkretnych rejestrów(odpowiedzialnych za obsługę transmisji po łączu szeregowym).
Poniżej przedstawiam te funkcje:

void OutPort(unsigned short int IO_port,char Value)
{
  asm("outb %%al,%%dx;"
  : //no output data
  :"d"(IO_port),"a"(Value) //input data (EDX<-IO_port; AL<-Value)
  );
}
char InPort(unsigned short int IO_port)
{
  asm("inb %%dx,%%al;"
  : //output data is in al register
  :"d"(IO_port) //input data (EDX<-IO_port AL<-Value)
  );
}

/*      Intel Syntax
      OUT PORT
      mov dx,IOport
      mov al,Value
      out dx,al
      IN PORT
      mov dx,IOport
      in al,dx
      mov rueck,al
*/
Dzięki dokumentowi HOW-TO ( http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html)"przegryzłem się " już przez róznice między asmeblerem Intela a Unixa. I nawet program ktory napisałem daje się kompilować przez GCC. Jest jednak jedno ale: otóż program działa dobrze do momentu pojawienia się w kodzie odwołań do tych funkcji (InPort i OutPort). Gdy je już napotka............to nie wykonuje już pozostałych instruckji, ktore sa poniżej tylko kończy wykonywanie programu(wiec dostęp do tej przestrzeni powoduje jakiś "fatal error" i zakończenie wykonywania programu). Nie wiem czy to może miec związek z tym ze Debian ma jakieś restrykcje odnośnie dostępu do przestrzeni I/O komputera? Sytuacja jest taka sama gdy próbuje napisać funkcje odczytujące i zapisujące słowo do pamięci.

Może ktoś z was spotkał sie z podobnym problemem albo ma więcej doświadczenia w pisaniu wstawek asemblerowych Unix dla GCC?

A i prosta wstawka jak np. incrementacja liczby napisana w asemblerze działa(poniżej przedstawiam jej kod):

int incr(int a){
asm volatile ("addl $0x01,%%eax;"
    : /* no output operand */
    : "a"(a) //"a" oznacza eax tak samo "c" oznacza ecx
   );
}
Więc kompilator kompiluje funkcje zawierajace wstawki asemblerowe........ale dlaczego nie dziala w przypadku dostepu do pamieci i obsługi przestrzeni I/O??

Dziękuje za wszelką pomoc i pozdrawiam,
Łukasz Majewski



Reply to: