Arquitectura de PCs Secuencia de compilación de un programa
Introducción La utilización de un enlazador con el ensamblador NASM permite la generación de programas COM a partir de uno o más archivos objeto Aplicación: laboratorio 2 y trabajo de fin de curso
Generación de un programa Generación de ejecutable COM con NASM a partir de varios fuentes, utilizando el enlazador VAL: Archivo Fuente 1 Archivo Fuente 2 Archivo Fuente N Archivo Objeto 1 Formato OBJ NASM VALArchivo Ejecutable COM NASM Archivo Objeto 2 Formato OBJ NASM Archivo Objeto N Formato OBJ
NASM Generación de un programa Ensamblado de archivo fuente tiene 2 pasos: Preprocesamiento por preprocesador Ensamblado por ensamblador PREPROCESADOR Archivo Objeto ENSAMBLADOR Archivo Preprocesado Archivo Fuente Procesa directivas a preprocesador Procesa directivas a ensamblador y pasa instrucciones ASM a código de máquina %define DOSWRITE 09h section.text org 100H movah,DOSWRITE movdx,HI int21h ret HI db ‘Buen dia!$’ Directiva al preprocesador section.text org 100H movah,09h movdx,HI int21h ret HI db ‘Buen dia!$’ Directivas al ensamblador Modificado por preprocesador B8 09 BA CD 21 C E
NASM Generación de un programa Archivo Fuente 1Archivo Fuente 2Archivo Fuente N PREPROCESADOR Archivo Preprocesado 2Archivo Objeto 2 ENSAMBLADOR Archivo Objeto N ENSAMBLADOR PREPROCESADOR Archivo Preprocesado N Archivo Preprocesado 1 PREPROCESADOR Procesa directivas a preprocesador Archivo Objeto 1 ENSAMBLADOR Procesa directivas a ensamblador y pasa instrucciones ASM a código de máquina VAL Archivo Ejecutable COM Combina secciones de los archivos objeto y resuelve referencias cruzadas entre archivos objeto
Generación de un programa El formato de archivo objeto generado por el ensamblador debe ser interpretable por el enlazador VAL procesa archivos “.OBJ” según formato OMF de Intel y Microsoft
Generación de un programa nasm -fobj [-o ArchivoObjeto>] [-l ArchivoListado] Sentencia general NASM para ensamblar un archivo fuente a formato OMF: Sentencia VAL para generar archivo COM a partir de N archivos objeto y archivo de mapeos con máximo nivel de detalle (5): val /CO /MP /DE:5..,,
Generación de un programa Por ej., secuencia que genera ejecutable COM a partir de 2 archivos fuente, generando archivos de listado y mapeo: nasm -fobj fuente1.asm -o fuente1.obj -l fuente1.lst nasm -fobj fuente2.asm -o fuente2.obj -l fuente2.lst val /CO /MP /DE:5 fuente1.obj fuente2.obj, comfile.com, mapfile.map
E C3 B4 09 BA CD 21 C E Generación de un programa extern FuncionHola section.text resb 100h..start: call FuncionHola ret global FuncionHola section.text FuncionHola: movah,09h movdx,hola int21h ret hola db ‘Buen dia!$’ Fuente 1 Fuente 2 Proceso completo: Directiva a NASM: FuncionHola importada Directiva a NASM: FuncionHola pública NASM Objeto 1 Código section.text: E C3 Símbolos importados: FuncionHola Ajustes: - relativo a dirección del (byte - siguiente al) dato, offset 1 de - código, símbolo FuncionHola Símbolo..start (inicio de código) en offset 100h de sección.text Código section.text: B4 09 BA CD 21 C E Símbolos públicos: FuncionHola en offset 0000 Objeto 2 Ajustes: - - relativo a inicio de segmento, - offset 3 de código VAL E C3 B4 09 BA 0C 01 CD 21 C E Ojo con el orden!!! val /co objeto1.obj objeto2.obj, exec.com
NASM extern FuncionHola ;Imprime Buen dia! section.text resb 100h..start: call FuncionHola ret Archivo preprocesado Fuente del formato OBJ (OMF) Directiva %include: %include “Fuente2.inc” section.text resb 100h..start: call FuncionHola ret global FuncionHola section.text FuncionHola: movah,09h movdx,hola int21h ret hola db ‘Buen dia!$’ Fuente1.ASMFuente2.asm extern FuncionHola ;Imprime Buen dia! Fuente2.inc PREPROCESADOR ENSAMBLADOR Sustitución textual por Fuente2.inc
Fuente del formato OBJ (OMF) Organización del programa: uno de los archivos objeto, el “archivo objeto principal”, guía la ejecución accediendo funciones en otros archivos objeto DEF “Archivo fuente principal”: fuente de “archivo objeto principal” Formato del fuente principal difiere del formato de los demás fuentes
Fuente del formato OBJ (OMF) Esqueleto de fuente principal (Archivo1.ASM): %include “Archivo2.inc”... %include “ArchivoN.inc” segment code RESB 100h..start:... Más directivas %include Última directiva %include Directiva a ensambladar: sentencias que siguen en segmento code Reserva 100H B al inicio del segmento para la PSP. Código inicia en offset 100H Directiva a ensamblador: punto de entrada al programa Sentencias ASM código del programa
Fuente del formato OBJ (OMF) Existe un archivo “INC” por cada fuente que declara símbolos globales extern simbolo1_archivoX extern simbolo2_archivoX Directiva: ”simbolo1_archivoX" es extern Directiva: ”simbolo2_archivoX" es extern Archivo X.INC contiene símbolos global de ArchivoX.ASM bajo directiva EXTERN:
Fuente del formato OBJ (OMF) %include “Archivo2.inc”... %include “Archivo[X-1].inc” %include “Archivo[X+1].inc”... %include “ArchivoN.inc” global simbolo_1_archivoX global simbolo_2_archivoX... segment code... Más directivas %include NO se incluye ArchivoX.inc Más directivas %include Última directiva %include Declaraciones global asociadas a extern de ArchivoX.inc Sentencias que siguen en segmento code Código ASM del programa Esqueleto de fuente no principal (ArchivoX.ASM):
Arquitectura de PCs Funciones implementadas por los docentes
Introducción Funciones implementadas por los docentes: Formato en adelante: Funciones de entrada salida: ioasm.obj, ioasm.inc Funciones de manejo de interrupciones: hook.obj, hook.inc Funciones de temporización: delayt2.obj, delayt2.inc Funciones misceláneas: misc.obj, misc.inc DescripciónFunción Código ejemploComentarios código ejemplo
Especificación Entrada salida Uso de funciones de entrada salida: %include “ioasm.inc”, enlace con ioasm.obj Imprime valor entero AX a pantallaprint_int mov ax, 098Ah call print_intImprime ‘098A‘ en pantalla Imprime fin de línea en pantallaprint_nl call print_nlImprime fin de línea Imprime carácter AL en pantallaprint_char mov al, ‘C’ call print_charImprime ‘C’
Especificación Entrada salida Imprime string nulo apuntado por AX en pantallaprint_string Devuelve en AX carácter ingresado en el tecladoread_char StrIngrese db ‘Ingrese caracter:’,0 mov ax, StrIngrese call print_string call read_char call print_char Imprime “Ingrese carácter:” Lee carácter del teclado Imprime carácter leído Devuelve en AX el número entero ingresado en el tecladoread_int PRINT_STRING_MACRO MACRO (preprocesador): expande en print_string PRINT_NL_MACRO MACRO (preprocesador): expande en print_nl
Especificación Uso de funciones de manejo de interrupciones: %include “hook.inc”, enlace con hook.obj Devuelve vector de interrupción AL en dirección ES:DIget_int_vector int_81h_prev resw 2 mov ax,cs mov es,ax mov di,int_81h_prev mov al, 081h call get_int_vector Vector 81h [int_81h_prev] = offset int 81h [int_81h_prev+2] = segmento int 81h Interrupciones
Especificación Uso de funciones de entrada salida: %include “hook.inc”, enlace con hook.obj Inicia vector de interrupción AL a valor apuntado por ES:BXset_int_vector int_81h_nuevo resw 2 int_81h: iret mov ax, int_81h mov [int_81h_nuevo], ax mov ax,cs mov [int_81h_nuevo+2], ax mov ax,cs mov es,ax mov bx, int_81h_nuevo mov ax, 81h call set_int_vector Offset del vector Segmento del vector ES:BX = CS:int_81h_nuevo Interrupción 81h Apunta vector 81h a rutina “int81h” Interrupciones
Incluye macros: GET_IRQHOOKENABLE_MACRO IRQHOOK_ENABLE_MACRO IRQHOOK_DISABLE_MACRO Utilizan vector de interrupción 82h como variable de estado Especificación Interrupciones
Especificación Uso de funciones de temporización: %include “delayt2.inc”, enlace de delayt2.obj Genera un retardo de AX msegdelayt2 mov ax,1000 call delayt2Retardo de 1000 mseg Temporización y Misceláneas Uso de funciones de misceláneas: %include “misc.inc”, enlace de misc.obj Devuelve en DX y AX dirección física de dirección lineal DX:AXlogic2phys buffer resb 512 mov ax, buffer mov dx, ds call logic2phys Reserva 512B en offset buffer ax = buffer dx = segmento dx_ax = dirección física de buffer
Arquitectura de PCs Ejemplo: programa residente
Programa residente El laboratorio 2 consiste en la implementación de un programa residente en memoria Se desarrollan conceptos sobre la base de un ejemplo: COMHOOK Intercepta interrupción 81h Imprime en pantalla “Int 81h” cada vez que se ejecuta interrupción 81h
Ejemplo: dos programas no residentes 00000H DOS 01000H INI_MEM 09000H 09000H 09100H Memoria disponible FFFFFH C:\> P1.COM PSP(P1) P1 PSP(P2) P2 C:\> P2.COM Programa residente
Ejemplo: programa 1 con 300H bytes residentes 00000H DOS 01000H INI_MEM 09000H 09000H 09100H Memoria disponible FFFFFH C:\> P1.COM C:\> P2.COM INI_MEM 09300H 09300H PSP(P1) P1 PSP(P2) P H Programa residente
Operación básica COMHOOK 00000H DOS 01000H INI_MEM 09000H FFFFFH C:\> 00204H0000:0000H Vector 81H (4 bytes) 0900:0113H Programa residente C:\> IRQ81.COM 09190H INI_MEM 09190H 0000:0000H 0900:02A3H C:\> IRQ81.COM Int 81h C:\> 09000H 09100H 09113H PSP JMP 0081H ATENCION INT 81H PREVIO INICIALIZACION 09181H COMHOOK.COM PSP IRQ81.COM 09290H 09311H PSP JMP 0081H ATENCION INT 81H INICIALIZACION PREVIO PSP 092A3H 0900:0113H INI_MEM 09320H 09320H section.text org 100h int81h ret Int 81h C:\> COMHOOK.COM
DOS INI_MEM 09000H Inicialización COMHOOK 00000H 01000H INI_MEM 09190H 09190H INI_MEM 09190H FFFFFH 00204H0000:0000H 09000H 09100H 09113H PSP JMP Initialize ATENCION INT 81H DATOS INICIALIZACION 09181H Int81h_Sign db ‘Int 81h’,0 vector_81h_prev resw 2 lds_low resw 2 RESIDENT_LENGTH equ END_RESIDENT – START_RESIDENT mov di,vector_81h_prev mov ax,81h call get_int_vector mov ax,int_81h mov [vector_81h],ax mov ax,cs mov [vector_81h+2],ax mov bx,vector_81h mov ax,81h call set_int_vector mov dx,PSP_SIZE+RESIDENT_LENGTH int 27h vector_81h resw 2 C:\> COMHOOK.COM Programa residente Carga vector 81h anterior en vector_81h_prev Construye vector 81h nuevo en vector_81h Carga vector 81h nuevo Termina manteniendo DX bytes iniciales del programa residentes 0900:0113H 0000:0000H 113H 900H 100H + 81H
Interrupción COMHOOK 00000H DOS 01000H INI_MEM 09190H 09190H INI_MEM 09190H FFFFFH 00204H 0000:0000H 09000H 09100H 09113H PSP JMP Initialize ATENCION INT 81H DATOS Int81h_Sign db ‘Int 81h’,0 vector_81h_prev resw 2 lds_low resw 2 pusha push ds mov ax,cs mov ds,ax mov [lds_low],bx pop bx mov [lds_low+2],bx mov ax,Int81h_Sign PRINT_STRING_MACRO PRINT_NL_MACRO mov ax,[vector_81h_prev] cmp ax,0 jne cadena mov ax,[vector_81h_prev+2] cmp ax,0 jne cadena popa lds bx,[lds_low] iret cadena: popa push word [vector_81h_prev + 2] push word [vector_81h_prev] lds bx,[lds_low] retf C:\> COMHOOK.COM C:\> INT81.COM Programa residente alternativa :0113H 0000:0000H INT81.COM PSP int 81h ret Cambio de contexto: respalda registros y apunta DS a segmento actual Imprime mensaje en pantalla Int 81h Verifica si vector previo nulo Si vector previo nulo, restaura registros (contexto) y termina Si vector previo no nulo, restaura registros (contexto) y pasa control a vector previo DS=919H DS=900 Segmento Offset
Interrupción COMHOOK 00000H DOS 01000H INI_MEM 09190H 09190H INI_MEM 09190H FFFFFH 00204H0000:0000H 09000H 09100H 09113H PSP JMP Initialize ATENCION INT 81H DATOS 0900:0113H Int81h_Sign db ‘Int 81h’,0 vector_81h_prev resw 2 lds_low resw 2 ds_bak resw 1 pusha push ds mov ax,cs mov ds,ax pop bx mov [ds_bak],bx mov ax,Int81h_Sign PRINT_STRING_MACRO PRINT_NL_MACRO mov ax,[vector_81h_prev] cmp ax,0 jne cadena mov ax,[vector_81h_prev+2] cmp ax,0 jne cadena popa push ax mov ax, [ds_bak] mov ds, ax pop ax iret cadena: popa push word [vector_81h_prev + 2] push word [vector_81h_prev] push ax mov ax,[ds_bak] mov ds,ax pop ax retf C:\> COMHOOK.COM C:\> INT81.COM Programa residente: alternativa 2 INT81.COM PSP int 81h ret Cambio de contexto: respalda registros y apunta DS a segmento actual Imprime mensaje en pantalla Int 81h Verifica si vector previo nulo Si vector previo nulo, restaura registros (contexto) y termina Si vector previo no nulo, restaura registros (contexto) y pasa control a vector previo DS=919H DS=900 Segmento Offset