2013-03-09 10 views
6

Chciałbym utworzyć samodzielną funkcję C, która drukuje ciąg znaków. To byłby część systemu operacyjnego, więc nie mogę używać stdio.h. Jak utworzyć funkcję, która wypisuje ciąg, który do niego przechodzę, bez konieczności używania stdio.h? Czy muszę napisać to na zgromadzeniu?Samodzielna procedura C do drukowania ciągów

+0

Co to jest system operacyjny? – md5

+1

czy zaglądasz do wnętrza stdio.h? – JuanPi

+0

@JuanPi OP powiedział, że nie może używać 'stdio.h'. – Rob

Odpowiedz

3

Najprawdopodobniej będziesz chciał spojrzeć na źródło, a może po prostu użyć go, do biblioteki stdio functions w bibliotece FreeBSD C, na licencji BSD.

Aby faktycznie produkować dane wyjściowe, potrzebujesz przynajmniej niektórych funkcji, które mogą zapisywać znaki w urządzeniu wyjściowym. Aby to zrobić, procedury stdio kończą się wywoływaniem write, który wykonuje syscall w jądrze.

+0

Jeśli OP chce, aby był "częścią systemu operacyjnego", nie może rozsądnie używać wywołania systemu operacyjnego, które go implementuje. –

+0

@IraBaxter: Tak. Byłaby to część, którą musiałby wdrożyć. Myślałem, że to oczywiste, że nie będzie nazywać jądra * BSD. – sfstewman

+1

Mówisz w zasadzie o przeniesieniu biblioteki C do systemu hobbistycznego, co jest powszechną rzeczą do zrobienia, ale dość daleko w dół do PO. Prawdopodobnie powinien zacząć od odczytu/zapisu bezpośrednio do pamięci wideo. –

4

Zakładając, że robisz to na komputerze X86, musisz odczytać/zapisać bezpośrednio do pamięci wideo znajdującej się pod adresem 0xB8000. W przypadku monitorów kolorowych należy podać bajt znaków ASCII i bajt atrybutów, który może wskazywać kolor. Powszechne jest używanie makr podczas uzyskiwania dostępu do tej pamięci:

#define VIDEO_BASE_ADDR 0xB8000 
#define VIDEO_ADDR(x,y) (unsigned short *)(VIDEO_BASE_ADDR + 2 * ((y) * SCREEN_X_SIZE + (x))) 

Później pisze się własne procedury IO. Poniżej znajduje się prosta funkcja, którą napisałem z bufora ekranowego. Użyłem tego, aby pomóc w implementacji prostej funkcji przewijania.

void c_write_window(unsigned int x, unsigned int y, unsigned short c) 
{ 
    if ((win_offset + y) >= BUFFER_ROWS) { 
    int overlap = ((win_offset + y) - BUFFER_ROWS); 
    *VIDEO_ADDR(x,y) = screen_buffer[overlap][x] = c; 
    } else { 
    *VIDEO_ADDR(x,y) = screen_buffer[win_offset + y][x] = c; 
    } 
} 

Aby dowiedzieć się więcej na ten temat i inne tematy osdev patrz http://wiki.osdev.org/Printing_To_Screen

+3

Jest to możliwe tylko w systemach/kartach graficznych, które implementują pamięć wideo "mapowaną na znaki"; z wyjątkiem sprzętu PC, tj. komputerów opartych na procesorach x86/x64 z kartami graficznymi, które mają BIOS typu "VGA" (wywołaj to, jeśli chcesz, typ sterownika urządzenia), tak nie jest; funkcja mapowania znaków na kartach graficznych typu PC jest wykonywana przez BIOS, a nie przez kartę. Aby to zrobić, powiedzmy, RaspberryPI, musisz napisać _Framebuffer Device Driver_. Wykorzystanie funkcji BIOS VGA nie jest więc (dużo) inne niż użycie sterownika konsolowego przez wywołanie systemowe 'write()'. –