#define RAMSCREEN 0xB8000 /* debut de la memoire video */ #define SIZESCREEN 0xFA0 /* 4000, nombres d'octets d'une page texte */ #define SCREENLIM 0xB8FA0 char kX = 0; /* position en X du curseur */ char kY = 10; /* position en Y du curseur */ char kattr = 0x07; /* nline = nombre de lignes a scroller (de 0 a 25) */ void scrollup (unsigned int nline) { unsigned char* video, *tmp; for(video=(unsigned char*)RAMSCREEN ; video<(unsigned char*)SCREENLIM ; video++){ tmp = (unsigned char*) (video+nline*160); if(tmp<(unsigned char*)SCREENLIM) *video = *tmp; else *video = 0; } kY-=nline; if(kY<0) kY=0; } void print (char* string) { char* ptr; /* pointeur sur la chaine de caractere */ unsigned char* video; ptr = string; while(*ptr!=0){ /* tant que le caractere est different de 0x0 */ if(*ptr==10){ /* CR-NL */ kX=0; kY++; } else{ video = (unsigned char*) (RAMSCREEN+2*kX+160*kY); *video = *ptr; *(video+1) = kattr; kX++; if(kX>79){ kX = 0; kY++; } } ptr++; if(kY>24) scrollup(kY-24); } } |
[BITS 32] EXTERN scrollup, print GLOBAL _start _start: mov eax, msg push eax call print pop eax mov eax, msg2 push eax call print pop eax mov eax,2 push eax call scrollup end: jmp end msg db 'un premier message',10,0 msg2 db 'un deuxieme message',10,0 |
extern void scrollup (unsigned int); extern void print (char*); int main(); void _start(void) { main(); } int main(void) { print("un message\n"); print("un autre message\n"); scrollup(2); while(1); } |
L'option -Ttext indique l'addresse lineaire a partir de laquelle le code commence. Par defaut, ld suppose que le code commence a l'adresse 0. Ce parametre est indispensable a ld car le code du noyau est recopie par notre secteur de boot a l'adresse 0x1000.
L'option -Tdata n'est pas utilisee ici. Elle sert a indiquer l'offset de debut de la section de donnees. Dans le cas present, on utilise pour cette zone les parametres par defaut : la zone de donnees suit la zone de texte (on remarque qu'elle relogee une page memoire plus loin).