Asm en procesadores de la serie 8086

Espero poder encontrar algo de ayuda aquí en el foro. Se que normalmente no se habla de cosas de este estilo.. a ver que tal. Mi problema es el siguiente: se trata de hacer un programa que interactue con un .com (se me ha olvidado comentar que se trabaja desde ms-dos).

Este fichero ".com", supongamos que se llama driver, ofrece una interrupción que me permite trabajar con el altavoz del PC de una forma "más amigable". Podemos verle como una caja negra, de la que sabemos que dicha interrupción es la 61h, para asuntos del vector de interrupciones, que como medida de prevención guarda en memoria la palabra 0FECAh y además si llamamos a esta interrupción con AH = 0 nos devuelve un código de estado.

El problema que tengo, no es a la hora de ejecutar las interrupciones y demás, viene a la hora de comprobar que realmente está cargado [snif] Copio el código:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Se comprueba la instalacion previa del driver   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   xor ax,ax      ;1.-Que existe dicha interrupcion
   mov es,ax   
   mov dx, es:186h      ;es = 0
   mov ax, es:184h
   or ax, dx      ;Que el or de ambos sea 0 implica que ambos son cero.
   cmp ax, 0
   je fin
   

;   mov ax, 186h      ;2.- Que esta almacenado el valor en la dir de memoria correspondiente
;   mov es,ax
;   mov ax, es:[184h+3h]
;   cmp ax, 0CAFEh
;   jne fin
   
   
   xor ah,ah      ;3.-Que responde con el estado correcto
   int 61h
   cmp ax,0ee01h   
   jne fin


Explico por si algo no queda claro:
1.- Cuando cargo el driver en el vector de interrupciones, se modifica el contenido de las celdas 184h y 186h. Recuerdo que es la interrupción 61h, es decir 61h*4=184h. No lo comenté pero cuando me refiero a h quiero decir hexadecimal. Volviendo al vector, si el or del contenido de ambas celdas es 0, significa que 184 y 186 están a 0, por tanto no existe dicha interrupción y salimos del programa.

3.-Compruebo el retorno de dicha interrupción cuando se pregunta por su estado.

2.- ¿¿¿??? Aquí mi problema. La interrupción se referirá a una dir de memoria apuntada por un offset y un segmento. Dado que trabajamos con una arquitectura big endian, 184h será la dirección del offset y 186h la dir del segmento. A su vez en el enunciado nos indican que 3 posiciones de memoria después de la dirección apuntada por ese segmento y offset está la palabra 0FECAh. (A la hora de comparar... de nuevo, como es big endian comparamos con CAFE, aunque de esto último no estoy del todo seguro).

Algo me falla en el punto 2, pero creo que estoy accediendo a la dirección correcta, utilizó el segmento extra para referirme a la posición de memoria donde habita el contenido driver... me estoy volviendo loco! [buuuaaaa] Cualquier sugerencia será bien recibida. [risita]
si es big endian no se compararia con ACEF0?
hace mucho que no me miro asm de los 8086
mas o menos desde que se usa EAX y demas
lo que no acabo de comprender es teniendo 65535 bytes de memoria
en un .com como no puedes usar algun push modificar registros y recuperar con un pop
para comparar

no se ya te digo que hace la tira de estas cosas
No no, aunque sea big endian, cada vez que accedemos a memoria traemos byte a byte la información pedida (en este caso como hablamos del registro AX, son 16 bits), no de 4 bits en 4 bits. En cuanto a lo que dices del stack, ¿qué valor comentas que debiera guardar? No termino de entender que es lo que estás proponiendo... :(
mira que hacerme repasar estas cosas
Imagen
Imagen
otra cosa
por que no usas estos registros
Source Index (SI) is a 16-bit register. SI is used for indexed, based indexed and register indirect addressing, as well as a source data address in string manipulation instructions.
Destination Index (DI) is a 16-bit register. DI is used for indexed, based indexed and register indirect addressing, as well as a destination data address in string manipulation instructions.


tengo la cabeza demasiado espesa
Veamos... utilizo el registro es (extra segment) para acceder a otra dirección de memoria que con ss, cs y ds me es imposible. Si bien es verdad que a lo mejor podría haber hecho un push de ds y sobreescribir sus valores, preferí hacerlo así. Una vez que puedo acceder a esas direcciones, es indiferente en que registro guarde los valores. Mi código finalmente ha quedado así:


   mov ax, es:[186h]      ;2.- Que esta almacenado el valor en la dir de memoria correspondiente
   mov bx, es:[184h]   
   mov es,ax
   mov ax, es:[bx+3]
   cmp ax, 0CAFEh
   jne fin



¿El problema? Que accedía a la dirección 186h:184h, pero esto estaba mal, en realidad era [0:186h]:[0:184h] donde los corchetes indican el valor almacenado en dichos pares segmento/offset. Muchas gracias por tu atención [risita] Problema solucionado.
4 respuestas