Diseño de Sistemas Operativos Ingeniería Superior de Informática SOLUCIONES A LAS PRACTICAS GUIADAS #1 - #4 Curso 2005/06 Práctica #1 Fichero PR1.C #include <dos.h> void far beep (void) { // El compilador ya guarda el bp del proceso // interrumpido y actualiza el sp asm push ax asm push cx asm asm asm asm asm mov out mov out out al, 0b6h 043h, al al, 005h 042h, al 042h, al asm in al, 061h asm or al, 03h asm out 061h, al /* ax = 10110110Bin */ /* #2 = 0505Hex */ /* ax = puerto B 8255 */ /* poner a 1 los bits #0 y #1 */ asm mov cx, 65535 retraso1: asm loop retraso1 asm mov cx, 65535 retraso2: asm loop retraso2 asm mov cx, 65535 retraso3: asm loop retraso3 asm in al, 061h asm and al, 0fch asm out 061h, al } asm asm asm asm asm /* poner a 0 los bits #0 y #1 */ pop cx pop ax mov sp,bp pop bp iret void main() { unsigned sg, of; void far *b; } b = beep; sg = FP_SEG(b); of = FP_OFF(b); asm push es asm xor ax, ax asm mov es, ax // El segmento de tabla vect. Intr. es el 0 asm cli asm mov bx, 01fch /* 7FHex * 4 */ asm mov ax, of asm mov word ptr es:[bx], ax asm add bx, 2 asm mov ax, sg asm mov word ptr es:[bx], ax asm sti asm pop es asm int 07Fh Práctica #2 Fichero PR2.C #include <stdio.h> #include <dos.h> void far { asm asm asm asm asm asm asm asm asm beep (unsigned p, unsigned long d) push ax push cx push dx mov out mov out mov out al, 0b6h /* ax = 10110110Bin */ 043h, al ax, word ptr [bp+6] 042h, al /* #2 = p */ al, ah 042h, al asm in al, 061h asm or al, 03h asm out 061h, al /* ax = puerto B 8255 */ /* poner a 1 los bits #0 y #1 */ asm mov cx, word ptr [bp+8] asm mov dx, word ptr [bp+10] retraso: asm asm asm asm loop retraso mov cx, 0FFFFh dec dx jne retraso asm in al, 061h asm and al, 0fch asm out 061h, al } /* poner a 0 los bits #0 y #1 */ asm pop dx asm pop cx asm pop ax void main() { unsigned long i; } for( i=1; i<65535; i+=1000 ) { printf("i=%u\n", (unsigned) i); beep((unsigned) i, 128000); } Práctica #3 Fichero PR3.C #include <stdio.h> #include <stdlib.h> #include <dos.h> char unsigned char far char buffer[32769]; length; *cact; endflag = 0; /* /* /* /* 32 Kb */ tamaño del fichero */ carácter a visualizar */ fin visualización */ void interrupt spooler (void) { asm lds bx, dword ptr cact asm mov ax, length asm or ax, ax asm jne visualizar asm mov byte ptr endflag, 1 asm jmp salir visualizar: asm mov asm mov asm int asm inc asm mov asm dec al, byte ptr ds:[bx] ah, 0eh 10h bx word ptr cact, bx length /* ds -> seg. datos */ /* más caracteres ? */ /* guarda offset en cact */ salir: ; } void main (int { FILE unsigned void far char argc, char **argv) *f; sg, of; *b; c, i, j, x = 0; if (argc < 2) exit(1); f = fopen(argv[1], "rt"); length = 0; while(!feof(f)) { c = fgetc(f); switch (c) { case '\n' : buffer[length++] = 13; /* CR */ buffer[length++] = 10; /* LF */ x = 0; break; case '\t' : j = 7 - (x & 0x07); for( i=0; i<=j; i++, x++ ) buffer[length++] = ' '; break; default : buffer[length++] = c; x++; break; } } fclose(f); Práctica #3 Fichero PR3.C cact = (char far *) buffer; b = spooler; sg = FP_SEG(b); of = FP_OFF(b); asm push es asm xor ax, ax asm mov es, ax asm cli asm asm asm asm asm mov mov mov mov mov bx, 70h ax, word word ptr ax, word word ptr asm asm asm asm mov mov mov mov ax, of word ptr es:[bx], ax ax, sg word ptr es:[bx+2], ax ptr es:[bx] b, ax ptr es:[bx+2] b+2, ax /* 1CHex * 4 */ /* guardamos vector */ /* instal. nuevo vect. */ asm sti asm pop es while (!endflag); asm push es asm xor ax, ax asm mov es, ax asm cli asm asm asm asm asm mov mov mov mov mov bx, 70h ax, word word ptr ax, word word ptr asm sti asm pop es } ptr b es:[bx], ax ptr b+2 es:[bx+2], ax /* restaurar vector */ Práctica #4 void extern writetxt ( unsigned char atr, unsigned char x, unsigned char y, char *s void extern cls ( unsigned char atr ); void main () { unsigned char x, y; cls(0x17); for(x=1; x<79; x++) { writetxt(0x0F,x,1,"-"); writetxt(0x0F,x,24,"-"); } } for(y=2; y<24; y++) { writetxt(0x0F,1,y,"!"); writetxt(0x0F,78,y,"!"); } Fichero PR4.C ); Práctica #4 Fichero TEXT.ASM TEXT_TEXT SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:TEXT_TEXT PUBLIC _writetxt, _cls _writetxt PROC FAR push bp mov bp, sp push push push push push push push push es ds ax bx cx dx si di mov ax, 0b800h mov es, ax mov mov mov mov xor mov mov xor lds ax, bl, ax, dl, dh, ax, cl, ch, si, word ptr [bp+6] al word ptr [bp+8] al dh word ptr [bp+10] al ch dword ptr [bp+12] mov shl shl shl shl shl shl shl shl shl shl add add shl mov ax, ax, ax, ax, ax, ax, ax, cx, cx, cx, cx, ax, ax, ax, di, cx 1 1 1 1 1 1 1 1 1 1 cx dx 1 ax cld mov ah, bl otro: lodsb or al, al jz fin stosw jmp otro fin: pop di pop si pop dx ; bl = atr ; dx = x ; cx = y ; ds:si = *s ; di = (y*80 + x)*2 Práctica #4 Fichero TEXT.ASM pop pop pop pop pop cx bx ax ds es mov sp, bp pop bp ret _writetxt ENDP _cls PROC FAR push bp mov bp, sp push push push push es ax cx di mov ax, 0b800h mov es, ax mov ax, word ptr [bp+6] mov ah, al ; ah = atr mov al, 32 ; al = ' ' mov di, 0 mov cx, 2000 cld rep stosw pop pop pop pop di cx ax es mov sp, bp pop bp ret _cls ENDP TEXT_TEXT ENDS END ; 25 * 80 Práctica #4 Línea de comandos Ensamblaje del fichero .asm: tasm /ml work\text.asm /ml para que el ensamblador conserve minúsculas/mayúsculas en los identificadores (por defecto, lo pasa todo a mayúsculas) Compilación/linkado del programa completo: bcc -ml -epr4.exe work\text.obj work\pr4.c -ml para seleccionar modo 'large' (las funciones han sido declaradas FAR; no necesariamente ha de ser así) Fijaros en el nombre del segmento de código en el fichero text.asm: <nombre de fichero = text>_TEXT. Se puede hacer también creando un fichero project con el listado de todos los ficheros que intervienen: text.obj pr4.c Antes de compilar, se ha de especificar el nombre del fichero project y se ha de seleccionar el modo large desde el entorno integrado.