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: