lunes, 12 de marzo de 2012

Desensamblador


Mientras leía un documento encontré que también existen algo llamado desensamblador, que como su nombre lo dice hace lo contrario de lo que hace el lenguaje ensamblador, es decir des-ensambla un programa previamente ensamblado.

Definición:

Un desensamblador es un programa de computadora que traduce el lenguaje de máquina a lenguaje ensamblador, la operación inversa de la que hace el ensamblador. Un desensamblador difiere de de un decompilador, en que éste apunta a un lenguaje de alto nivel en vez de al lenguaje ensamblador. la salida de un desensamblador, el desensamblado, es a menudo formateada para la legibilidad humana en vez de ser adecuada para la entrada a un ensamblador, haciendo que éste sea principalmente una herramienta de ingeniería inversa.

Como funciona:

El desensamblador transforma el código binario en instrucciones básicas del PC en la que se ejecuta, el programa no es capaz de distinguir si dichas instrucciones provienen de un "if", de un "for" o de un "while". Tampoco conoce los nombres de las variables (no se incluyen en el código binario ya que la máquina no usa nombres), así que suele inventar nombres como VAR_0001, VAR_0002, etc.
En cuanto a las funciones, algo parecido pasa con las funciones internas del programa, se suelen llamar CALL_0001 o JMP_0001, o similares, dependiendo de si son direcciones de llamadas con o sin retorno, respectivamente.
Las funciones externas son dependientes según el sistema en el que se corra el programa a desensamblar:
Bajo sistemas como DOS, la mayoría de las veces puede indicar las funciones que se llaman (llamar a una función requiere típicamente un llamado a interrupción con valores específicos en los registros, que deben ser consultados si no son provistos por el programa desensamblador).

 Como no funciona:

Un desensamblador no puede:
·         Rescatar los nombres de las variables o las funciones nombradas por el programador.
·         Recuperar los comentarios.
·         Rescatar código fuente perdido.
Existe una salvedad a todo esto y es cuando el que compiló el programa ha habilitado una opción, que es incluir la información de depuración en el programa (usualmente se trata de programas en fase de desarrollo y no de programas finales).

Donde se usan:

Los desensambladores son ampliamente utilizados para crackear programas y para realizar ingeniería inversa. También son utilizados por desarrolladores de software, investigadores o estudiantes.
Programas desensambladores:
Cualquier depurador interactivo incluirá una alguna forma de ver el desensamblado del programa que está siendo depurado. A menudo, la misma herramienta de desensamblado será empaquetada como un desensamblador independiente distribuido junto con el depurador. Por ejemplo, el objdump, parte del GNU Binutils, está relacionado con el depurador interactivogdb.
·         Interactive Disassembler (IDA)
·         ILDASM es una herramienta contenida en el SDK del .NET Framework. Puede ser usado para desensamblar los archivos PE conteniento código Common Intermediate Language
·         OllyDbg es un depurador analizador ensamblador de 32 bits
·         SIMON, un probador/depurador/animador con desensamblador integrado para el EnsambladorCOBOL y PL/1
·         Texe es un desensambladorde 32 bits y un analizador de archivos PE de Windows libre.
·         unPIC es un desensamblador para los microcontroladores PIC

Saltos, Ciclos, Operadores lógicos y más Instrucciones


Instrucciones

Una instrucción es un enunciado que se vuelve ejecutable cuando se ensambla un programa
El ensamblador traduce las instrucciones en bytes de lenguaje de maquina, para que el CPU los cargue y los lleve a cabo en tiempo de ejecución.

Una instrucción contiene cuatro partes básicas:

·         Etiqueta (opcional).
·         Nemónico de instrucción (requerido)
·         Operando(s) (por lo general, son requeridos)
·         Comentarios (opcional).

Ésta es la sintaxis básica:
[etiqueta:] nemónico operando(s) [comentarios]

Formato de una Instrucción

Un nemónico de instrucción es una palabra corta que identifica a una instrucción. En ingles, un nemónico es un dispositivo que ayuda a la memoria. De manera similar, los nemónicos de instrucciones en le lenguaje ensamblador, proporcionan sugerencias acerca del tipo de operación que realizan.

MOV   mueve un datos a un destino
ADD  suma dos valores
SUB   resta dos valores
JMP   salta a una nueva ubicación
CALL llama a un procedimiento

Un salto en lenguaje de maquina es hacer un cambio de secuencia del programa en direccionamiento en forma intencional.

Salto a direcciones mas bajas
23553     MOV AX,6500
 .
 .
 .
23567     JMP 23553

Salto a direcciones mas altas
D3A81     JMP D3A97
 .
 .
 .
D3A97    XCHG BH,DL
Ya que el direccionamiento de una instrucción es dado por los registros CS e IP,  estos son los que se moveran cuando se genere un salto.
D.R. = (CS * 10) + IP
Los saltos se pueden realizar dentro del mismo segmento o se pueden transferir a otro segmento diferente.
Saltos Condicionales


JXXX
Tiene un  tamaño de 8 bitsabarca de  00  hasta FF y tiene signo. XXX Representa la condición
Esta condición se maneja por medio de las banderas de estado: CF, OF, ZF, PF y SF.
El +128 significa que el desplazamiento es positivo. Valor hexadecimal del 00 al 7F, ejem.

JXXX  48


La manera tradicional de manejar la instrucción es colocar el valor del desplazamiento (positivo o negativo).

En el debug en el parámetro desplazamiento se coloca la dirección a donde va a saltar.

 
CICLOS

LOOP : Tiene un  tamaño de 8 bitsabarca de  00  hasta FF y tiene signo .

Ejecutar un BUCLE consiste en repetir “n” veces una serie de instrucciones de una sección del programa.

Esta instrucción, en el momento que se ejecuta, realiza los siguientes pasos:
1°Decrementa a CX en un uno.(CX=CX-1)

2°Checa el valor de CX, y
   -SI CX es diferente de cero, realiza el salto correspondiente de acuerdo al valor del desplazamiento.
   -Si CX es igual a cero, continua con la      siguiente instrucción debajo de ella.
Operadores lógicos

AND: FUNCION LOGICA “Y
OR: FUNCION LOGICA “O”
XOR: FUNCION LOGICA “O” EXCLUSIVO
TEST: FUNCION LOGICA “Y” SIN RESULTADO

Banderas afectadas: AF , ZF , PF , SF

Instrucciones para lenguaje ensamblador


MOV Instrucción de Transferencia de Datos (MOVER DATOS)
1) No se permite transferencias de memoria a memoria
2) Los datos tienen que ser del mismo tamaño
3) El destino no puede ser dato inmediato
4) Después de la transferencia, destino y fuente son iguales
5) No se permite transferencia inmediata a REG. SEG.
Diferentes Opciones

a)   MOV  REG2(8) , REG1(8)
b)   MOV  REG2(16) , REG1(16)
c)   MOV  REG(8) , DATO INM(8)
d)   MOV  REG(16) , DATO INM(16)
e)   MOV  REG(8) , MEM(8)
f)   MOV MEM(8) , REG(8)
g)   MOV  REG(16) , MEM(16)
h)   MOV  MEM(16) , REG(16)
i)   MOV  MEM(8) , DATO INM(8)
j)   MOV  MEM(16) , DATO INM(16)

Para poder identificar el tamaño del dato inmediato que se traslada a memoria tenemos que escribir un prefijo antes de la dirección efectiva, siendo estos:

MOV  BYTE PTR  MEM(8), DI(8)
MOV  WORD PTR  MEM(16), DI(16)


Conceptos de Stack
D.R. = (SS*10) + SP
El  sistema de apilación utiliza la  técnica LIFO(last in first out), el últi-mo en  entrar, primero en salir.
SP   apunta  al  último dato válido en el stack de memoria.
El limite inferior es el valor inicial que se le propone a SP
El stack de memoria es un rango de localidades de memoria que permite al programador apilar datos de byte en byte.
Solo puede manejar datos de 16 bits (palabra) y es un almacenamiento temporal.
PUSH: METERAL STACK DE MEMORIA
POP: EXTRAER DEL STACK DE MEMORIA
PUSHF: METER EL REG. DE BANDERAS
POPF: SACAR  AL REG. DE BANDERAS




Instrucciones para operaciones de Suma
Destino y fuente son los operandos que manejan las instrucciones de suma para realizar la operacion correspondiente. ambos operandos pueden ser de 8 o de 16 bits.
ADD
operando   +   operando  = resultado en
 destino          fuente          destino
ADC
operando   +   operando  +   cf  = resultado en
 destino          fuente                    destino
Tanto los operandos como el resultado son manejados en hexadecimal. no se aplica para registros segmentos.
Destino y fuente son los operandos que manejaran las instrucciones de resta para realizar la operacion correspondiente. ambos operandos pueden ser de 8 o de 16 bits.
SUB
OPERANDO   -   OPERANDO  = RESULTADO EN
 DESTINO          FUENTE          DESTINO
SBB
OPERANDO   -   OPERANDO  -   CF  = RESULTADO EN
 DESTINO          FUENTE                    DESTINO
tanto los operandos como el resultado son manejados en hexadecimal. no se aplica para registros segmentos.
Ajuste Decimal
el ajuste decimal  sirve para poder cambiar el resultado hexadecimal que producen las instrucciones de suma y resta a cantidades decimales (del 0 al 9), por ejemplo:
Si sumamos las cantidades de 7 y 5, la instrucción ADD obtendrá el resultado de “0C“, pero si queremos cambiarlo a decimal, aplicamos una instrucción de ajuste decimal y lo que se obtiene es la cantidad de "12".
es opcional el ajuste decimal, si es que se desea un resultado decimal, ya que son independientes de las instrucciones aritmeticas. por eso se manejan en forma separada y simpre despues de las operacion aritmetica.
Ajuste Decimal
Una clase de ajuste decimal es del tipo EMPAQUETADO que considera a cada byte dividido en dos nibbles y cada nibble representa un valor numérico del 0 a 9.
Solo se aplica este tipo de ajuste para las operaciones de suma  y resta.
Los requerimientos para el ajuste decimal empaquetado son:
Uno de los operándos debe de ser registro “AL”, ya que el ajuste solo se maneja en BYTE, por lo tanto, al realizar la instrucción aritmética el operando destino debe ser “AL”, por ejemplo:
ADD  AL,BL
Otro requisito es que los dos operándos tienen que ser dígitos numéricos (del 0 al 9). No se garantiza el ajuste si se aplican dígitos alfabéticos (del A al F), por ejemplo:
34    01  72  28 à  SI
1F  B8  DD  9E à  NO
Instrucción de Incremento
Esta instrucción toma al operando destino, que en un principio es fuente, posteriormente le suma uno y finalmente el resultado obtenido lo regresa al operando destino.
Instrucción de Decremento
Esta instrucción toma al operando destino, que en un principio es fuente, posteriormente le resta uno y finalmente el resultado obtenido lo regresa al operando destino.

Tipos de lenguaje Ensamblador

Aunque todos los ensambladores realizan básicamente las mismas tareas, podemos clasificarlos de acuerdo a características.
Así podemos clasificarlos en:
Ensambladores Cruzados (Cross-Assembler).
Se denominan así los ensambladores que se utilizan en una computadora que posee un procesador diferente al que tendrán las computadoras donde va a ejecutarse el programa objeto producido.
El empleo de este tipo de traductores permite aprovechar el soporte de medios físicos (discos, impresoras, pantallas, etc.), y de programación que ofrecen las máquinas potentes para desarrollar programas que luego los van a ejecutar sistemas muy especializados en determinados tipos de tareas.
Ensambladores Residentes.
Son aquellos que permanecen en la memoria principal de la computadora y cargan, para su ejecución, al programa objeto producido. Este tipo de ensamblador tiene la ventaja de que se puede comprobar inmediatamente el programa sin necesidad de transportarlo de un lugar a otro, como se hacía en cross-assembler, y sin necesidad de programas simuladores.
Sin embargo, puede presentar problemas de espacio de memoria, ya que el traductor ocupa espacio que no puede ser utilizado por el programador. Asimismo, también ocupará memoria el programa fuente y el programa objeto. Esto obliga a tener un espacio de memoria relativamente amplio. Es el indicado para desarrollos de pequeños sistemas de control y sencillos automatismo empleando microprocesadores(1).
La ventaja de estos ensambladores es que permiten ejecutar inmediatamente el programa; la desventaja es que deben mantenerse en la memoria principal tanto el ensamblador como el programa fuente y el programa objeto.
Macroensambladores.
Son ensambladores que permiten el uso de macroinstrucciones (macros). Debido a su potencia, normalmente son programas robustos que no permanecen en memoria una vez generado el programa objeto. Puede variar la complejidad de los mismos, dependiendo de las posibilidades de definición y manipulación de las macroinstrucciones, pero normalmente son programas bastantes complejos, por lo que suelen ser ensambladores residentes.
Microensambladores.
Generalmente, los procesadores utilizados en las computadoras tienen un repertorio fijo de instrucciones, es decir, que el intérprete de las mismas interpretaba de igual forma un determinado código de operación.
El programa que indica al intérprete de instrucciones de la UCP cómo debe actuar se denomina microprograma. El programa que ayuda a realizar este microprograma se llama microensamblador. Existen procesadores que permiten la modificación de sus microprogramas, para lo cual se utilizan microensambladores.
Ensambladores de una fase.
Estos ensambladores leen una línea del programa fuente y la traducen directamente para producir una instrucción en lenguaje máquina o la ejecuta si se trata de una pseudoinstrucción. También va construyendo la tabla de símbolos a medida que van apareciendo las definiciones de variables, etiquetas, etc.
Debido a su forma de traducción, estos ensambladores obligan a definir los símbolos antes de ser empleados para que, cuando aparezca una referencia a un determinado símbolo en una instrucción, se conozca la dirección de dicho símbolo y se pueda traducir de forma correcta. Estos ensambladores son sencillos, baratos y ocupan poco espacio, pero tiene el inconveniente indicado(1).
Ensambladores de dos fases.
Los ensambladores de dos fases se denominan así debido a que realizan la traducción en dos etapas. En la primera fase, leen el programa fuente y construyen una tabla de símbolos; de esta manera, en la segunda fase, vuelven a leer el programa fuente y pueden ir traduciendo totalmente, puesto que conocen la totalidad de los símbolos utilizados y las posiciones que se les ha asignado. Estos ensambladores son los más utilizados en la actualidad.

Microprocesador buses


Buses de comunicación en un circuito impreso.
En Arquitectura de computadores, el bus es un sistema digital que transfiere datos entre los componentes de un computador o entre computadores. Están formado por cables o pistas en un circuito impreso, dispositivos como resistencias y condensadores además de circuitos integrados.
En los primeros computadores electrónicos, todos los buses eran de tipo paralelo, de manera que la comunicación entre las partes de computador se hacía por medio de cintas o muchas pistas en el circuito impreso, en los cuales cada conductor tiene una función fija y la conexión es sencilla requiriendo únicamente puertos de entrada y de salida para cada dispositivo.
La tendencia en los últimos años es el uso de buses seriales como el USB, Firewire para comunicaciones con periféricos y el reemplazo de buses paralelos para conectar toda clase de dispositivos, incluyendo el microprocesador con el chipset en la propia placa base. Son conexiones con lógica compleja que requieren en algunos casos gran poder de computo en los propios dispositivos, pero que poseen grandes ventajas frente al bus paralelo que es menos inteligente.
Existen diversas especificaciones de bus que definen un conjunto de características mecánicas como conectores, cables y tarjetas, además de protocolos eléctricos y de señales.
Funcionamiento
La función del Bus es la de permitir la conexión lógica entre distintos subsistemas de un sistema digital, enviando datos entre dispositivos de distintos ordenes: desde dentro de los mismos circuitos integrados, hasta equipos digitales completos que forman parte de supercomputadoras.
La mayoría de los buses están basados en conductores metálicos por los cuales se trasmiten señales eléctricas que son enviadas y recibidas con la ayuda de integrados que poseen una interfaz del bus dado y se encargan de manejar las señales y entregarlas como datos útiles. Las señales digitales que se trasmiten son de datos, de direcciones o señales de control.
Los buses definen su capacidad de acuerdo a la frecuencia máxima de envío y al ancho de los datos. Por lo general estos valores son inversamente proporcionales: si se tiene una alta frecuencia, el ancho de datos debe ser pequeño. Esto se debe a que la interferencia entre las señales (crosstalk) y la dificultad de sincronizarlas, crecen con la frecuencia, de manera que un bus con pocas señales es menos susceptible a esos problemas y puede funcionar a alta velocidad.
Todos los buses de computador tiene funciones especiales como las interrupciones y las DMA que permiten que un dispositivo periferico acceda a una CPU o a la memoria usando el minimo de recursos.
Primera Generación
Bus Backplane del PDP-11 junto con algunas tarjetasLos primeros computadores tenían 2 sistemas de buses, uno para la memoria y otro para los demás dispositivos. La CPU tenia que acceder a dos sistemas con instrucciones para cada uno, protocolos y sincronizaciones diferentes.
La empresa DEC noto que el uso de dos buses no era necesaria si se combinaban las direcciones de memoria con los de los periféricos en un solo espacio de memoria (mapeo), de manera que la arquitectura se simplificaba ahorrando costos de fabricación en equipos fabricados en masa, como eran los primeros minicomputadores.
Los primeros microcomputadores se basaban en la conexión de varias tarjetas de circuito impreso a un bus Backplane pasivo que servía de eje al sistema. En ese bus se conectaba la tarjeta de CPU que realiza las funciones de arbitro de las comunicaciones con las demás tarjetas de dispositivo conectadas; las tarjetas incluían la memoria, controladoras de diskette y disco, adaptadores de vídeo. La CPU escribía o leía los datos apuntando a la dirección que tuviera el dispositivo buscado en el espacio único de direcciones haciendo que la información fluyera a través del bus principal.
Entre las implementaciones mas conocidas, están los buses Bus S-100 y el Bus ISA usados en varios microcomputadores de los 70′s y 80′s. En ambos, el bus era simplemente una extensión del bus del procesador de manera que funcionaba a la misma frecuencia. Por ejemplo en los sistemas con procesador Intel 80286 el bus ISA tenia 6 u 8 Mhz de frecuencia dependiendo del procesador.
Segunda generación
Jerarquia de diversos buses en un equipo moderno: SATA, FSB, AGP, USB entre otros. El hecho de que el bus fuera pasivo y que usara la CPU como control, representaba varios problemas para la ampliación y modernización de cualquier sistema con esa arquitectura. Ademas que la CPU utilizaba una parte considerable de su potencia en controlar el bus. Desde que los procesadores empezaron a funcionar con frecuencias mas altas, se hizo necesario jerararquizar los buses de acuerdo a su frecuencia: se creo el concepto de bus de sistema (conexión entre el procesador y la RAM) y de buses de expansión, haciendo necesario el uso de un Chipset para conectar todo el sistema.
El bus ISA utilizado como backplane en el PC IBM original paso de ser un bus de sistema a uno de expasión, dejando su arbitraje a un integrado del chipset e implementando un bus a una frecuencia mas alta para conectar la memoria con el procesador.
En cambio el bus Nubus era independiente desde su creación, tenia un controlador propio y presentaba una interfaz estandar al resto del sistema, permitiendo su inclusión en diferentes arquitecturas. Fue usado en diversos equipos, incluyendo algunos de Apple y se caracterizaba por tener un ancho de 32 bits y algunas capacidades Plug and play (autoconfiguración), que lo hacían muy versatil y adelantado a su tiempo. Entre otros ejemplos de estos buses autonomos, estan el AGP y el bus PCI.es algo q sirve para trasladar informacion
Tercera generación
Los buses de tercera generación se caracterizan por tener conexiones punto a punto, a diferencia de los buses arriba nombrados en los que se comparten señales de reloj, y otras partes del bus. Esto se logra reduciendo fuertemente el numero de conexiones que presenta cada dispositivo usando interfaces seriales. Entonces cada dispositivo puede negociar las características de enlace al inicio de la conexión y en algunos casos de manera dinámica, al igual que sucede en las redes de comunicaciones. Entre los ejemplos mas notables, estan los buses PCI-Express, el Infiniband y el Hyper Transport
Tipos de Bus
Existen dos grandes tipos clasificados por el método de envió de la información: bus paralelo o serial. Hay diferencias en el desempeño y hasta hace unos años se consideraba que el uso apropiado dependía de la longitud física de la conexión: para cortas distancias el bus paralelo,para largas el serial.
Bus paralelo
Es un bus en el cual los datos son enviados por bytes al mismo tiempo, con la ayuda de varias lineas que tienen funciones fijas. La cantidad de datos enviada es bastante grande con una frecuencia moderada y es igual al ancho de los datos por la frecuencia de funcionamiento. En los computadores ha sido usado de manera intensiva, desde el bus del procesador, los buses de discos duros, tarjetas de expansión y de vídeo, hasta las impresoras.
Diagrama de un Bus Backplane como extensión del bus de procesadorEl Front Side Bus de los procesadores Intel es un bus de este tipo y como cualquier bus presenta unas funciones en lineas dedicadas:
Las Lineas de Dirección son las encargadas de indicar la posición de memoria o el dispositivo con el que se desea establecer comunicación. Las Lineas de Control son las encargadas de enviar señales de arbitraje entre los dispositivos. Entre las más importantes están las lineas de interrupción, DMA y los indicadores de estado.
Las Lineas de Datos trasmiten los bits, de manera que por lo general un bus tiene un ancho que es potencia de 2.
Un bus paralelo tiene conexiones físicas complejas, pero la lógica es sencilla, que lo hace útil en sistemas con poco poder de computo. En los primeros microcomputadores, el bus era simplemente la extensión del bus del procesador y los demás integrados “escuchan” las linea de direcciones, en espera de recibir instrucciones. En el PC IBM original, el diseño del bus fue determinante a la hora de elegir un procesador con I/O de 8 bits (Intel 8088), sobre uno de 16 (el 8086), porque era posible usar hardware diseñado para otros procesadores, abaratando el producto.
Bus serie
En este los datos son enviados, bit a bit y se reconstruyen por medio de registros o rutinas de software. Está formado por pocos conductores y su ancho de banda depende de la frecuencia. Es usado desde hace menos de 10 años en buses para discos duros, tarjetas de expansión y para el bus del procesador.


Bibliografía:
http://www.apuntesdeelectronica.com/microprocesador/buses.htm

Banderas



REGISTRO DE ESTADOS O BANDERAS

Mientras hacia mi tarea de lenguaje ensamblador me encontré con algunos términos que no comprendía, por ejemplo que en el lenguaje ensamblador se utilizan las banderas. Las banderas son espacios en memoria.
Vamos a conocer las más comunes y sus funciones básicas.

X     BITS SIN USO
0 - 15  POSICIONES  BINIARIAS
F     INICIAL DE LA PALABRA FLAG

BANDERAS DE ESTADOS:
CF  ACARREO
PF  PARIDAD
AF  AUXILIAR
ZF  CERO
SF  SIGNO
OF  SOBREFLUJO 
Estas banderas serán alteradas por los resultados producidos  en la ejecución de instrucciones aritméticas y lógicas. 
BANDERAS DE CONTROL:
DF  DIRECCION
IF  INTERRUPCION
TF  DESVIO 

Estas banderas son alteradas por medio de instrucciones manejadas por el programador, para activarlas (1) o desactivarlas (0).  
Banderas de Estado

a)     Bandera de acarreo:  CF(Carry Flag) 
Este bit será alterado en su valor (1 o 0) por la ejecución de instrucciones aritméticas.
Para la suma y resta, cuando el resultado exceda el tamaño de los operandos manejados y el microprocesador no pueda entregarlo en sus registros de tamaño fijo, ésta bandera detectará dicho bit y lo almacenará hasta que se realice otra operación de suma o resta. Para la suma se le llama acarreo final y para la resta se le llama préstamo
b) Bandera de paridad PF (PARITY  FLAG)
Este bit será alterado en su valor por la ejecución de instrucciones aritméticas o lógicas.
La paridad es detectada en el byte menos significativo en el resultado de la operación y checará cuantos unos lógicos (1) existen.
Si la cantidad de “unos” en impar (1,3,5,7), se detectará una paridad IMPAR (ODD).
Si la cantidad de “unos” es par (0,2,4,6,8), se detectará una paridad PAR (EVEN).
c) Bandera de acarreo auxiliar AF (AUXILIARY CARRY  FLAG)
Este bit será alterado en su valor por la ejecución de instrucciones aritméticas.
El acarreo auxiliar será detectado por el que se produce de las unidades a las decenas (o del bit 3 al bit 4), y no en el resultado.
Esta bandera es utilizada principalmente en instrucciones que convierten resultados de hexadecimal a decimal (BCD).
d) Bandera de cero ZF (ZERO  FLAG)
Este bit será alterado en su valor por la ejecución de instrucciones aritméticas y/o lógicas.
La bandera de CERO será detectada cuando el resultado que se produce en la operación sea cero (igual a 0) o diferente de cero (no 0).
e) Bandera de signo SF (SIGN  FLAG)
Este bit será alterado en su valor por la ejecución de instrucciones aritméticas y/o lógicas.
El signo será detectado cuando el resultado que se produce en la operación sea positivo o negativo. Este se identifica en el bit más significativo del resultado.
f) Bandera de sobreflujo OF (OVERFLOW  FLAG)
Este bit será alterado en su valor por la ejecución de instrucciones aritméticas.
El sobre flujo será detectado cuando el resultado que se produce en la operación cambia de signo, contrario a los signos de los operandos manejados, éste se detecta en el bit más significativo. Si son positivos los operandos y cambia el resultado a negativo, o si son negativos los operandos y cambia el resultado a positivo.

Bibliografía:
http://www.apuntesdeelectronica.com/microcontroladores/microcontroladores-fundamentos-pic.htm

domingo, 4 de marzo de 2012

Ciclo de Vida de Aplicaciones y actividades en Android


A diferencia de la mayoría de los ambientes de trabajo, las aplicaciones de Android no pueden controlar su ciclo de vida. En lugar de eso, deben esperar eventos que cambien el estado de la aplicación, y reaccionar según el caso, incluyendo el caso de ser cerradas prematuramente.
Por defecto, cada aplicación de Android corre en su propio proceso (Aún que es posible forzar varias aplicaciones a compartir el mismo proceso, usando el atributo android:process dentro del Manifest). Cada aplicación corre su propia instancia de Dalvik, y la memoria y el manejo de recursos se manejan exclusivamente por Android.
Debido a los pocos recursos con los que los dispositivos de Android suelen contar, el Run Time maneja agresivamente los recursos, matando aplicaciones de baja prioridad para darle recursos a los que lo requieren (Generalmente, la aplicación con la que el usuario interactúa directamente)
El hecho de que cada aplicación se ejecuta en su propio proceso aporta beneficios en cuestiones básicas como seguridad, gestión de memoria, o la ocupación de la CPU del dispositivo móvil. Android se ocupa de lanzar y parar todos estos procesos, gestionar su ejecución y decidir qué hacer en función de los recursos disponibles y de las órdenes dadas por el usuario. 

   El usuario desconoce este comportamiento de Android. Simplemente es consciente de que mediante un simple clic pasa de una a otra aplicación y puede volver a cualquiera de ellas en el momento que lo desee. No debe preocuparse sobre cuál es la aplicación que realmente está activa, cuánta memoria está consumiendo, ni si existen o no recursos suficientes para abrir una aplicación adicional. Todo eso son tareas propias del sistema operativo. 

   Android lanza tantos procesos como permitan los recursos del dispositivo. Cada proceso, correspondiente a una aplicación, estará formado por una o varias actividades independientes (componentes Activity) de esa aplicación. Cuando el usuario navega de una actividad a otra, o abre una nueva aplicación, el sistema duerme dicho proceso y realiza una copia de su estado para poder recuperarlo más tarde. El proceso y la actividad siguen existiendo en el sistema, pero están dormidos y su estado ha sido guardado. Es entonces cuando crea, o despierta si ya existe, el proceso para la aplicación que debe ser lanzada, asumiendo que existan recursos para ello.
   Cada uno de los componentes básicos de Android tiene un ciclo de vida bien definido; esto implica que el desarrollador puede controlar en cada momento en qué estado se encuentra dicho componente, pudiendo así programar las acciones que mejor convengan. El componente Activity, probablemente el más importante.
Ciclo de vida de una actividad
  • onCreate(), onDestroy(): Abarcan todo el ciclo de vida. Cada uno de estos métodos representan el principio y el fin de la actividad.
  • onStart(), onStop():  Representan la parte visible del ciclo de vida. Desde onStart() hasta onStop(), la actividad será visible para el usuario, aunque es posible que no tenga el foco de acción por existir otras actividades superpuestas con las que el usuario está interactuando. Pueden ser llamados múltiples veces.
  • onResume(), onPause(): Delimitan la parte útil del ciclo de vida. Desde onResume() hasta onPause(), la actividad no sólo es visible, sino que además tiene el foco de la acción y el usuario puede interactuar con ella. 
   Tal y como se ve en el diagrama de la figura anterior, el proceso que mantiene a esta Activity puede ser eliminado cuando se encuentra en onPause() o en onStop(), es decir, cuando no tiene el foco de la aplicación. Android nunca elimina procesos con los que el usuario está interactuando en ese momento. Una vez se elimina el proceso, el usuario desconoce dicha situación y puede incluso volver atrás y querer usarlo de nuevo. Entonces el proceso se restaura gracias a una copia y vuelve a estar activo como si no hubiera sido eliminado. Además, la Activity puede haber estado en segundo plano, invisible, y entonces es despertada pasando por el estado onRestart().

   Pero, ¿qué ocurre en realidad cuando no existen recursos suficientes? Obviamente, los recursos son siempre limitados, más aun cuando se está hablando de dispositivos móviles. En el momento en el que Android detecta que no hay los recursos necesarios para poder lanzar una nueva aplicación, analiza los procesos existentes en ese momento y elimina los procesos que sean menos prioritarios para poder liberar sus recursos.

   Cuando el usuario regresa a una actividad que está dormida, el sistema simplemente la despierta. En este caso, no es necesario recuperar el estado guardado porque el proceso todavía existe y mantiene el mismo estado. Sin embargo, cuando el usuario quiere regresar a una aplicación cuyo proceso ya no existe porque se necesitaba liberar sus recursos, Android lo crea de nuevo y utiliza el estado previamente guardado para poder restaurar una copia fresca del mismo. Como se ya ha explicado, el usuario no percibe esta situación ni conoce si el proceso ha sido eliminado o está dormido.

Prioridad y Procesos

El orden en que los procesos se eliminan se determina por la prioridad de las aplicaciones en uso. Su prioridad se define por el componente de mayor prioridad. Si dos aplicaciones empatan, el proceso con menor prioridad por mas tiempo será eliminado primero.
La prioridad también se define en base a dependencias de otros procesos: Si una aplicación depende de un Service o Content Provider de otra aplicación, la aplicación secundaria tendrá por lo menos la misma prioridad que la aplicación que la necesita.
Por último, todas las aplicaciones de Android se quedan corriendo y en la memoria hasta que los recursos son requeridos por otras aplicaciones.
Los Procesos Activos son aquellos con los que el usuario interactúa. Android tiene como prioridad mostrar una interfáz que responde al usuario. Generalmente son pocos los procesos con esta prioridad, y solo serán eliminados como último recurso.
Entre los procesos activos tenemos:
·         Activities que estan visibles e interactuando con el usuario.
·         Broadcast Receivers ejecutando onReceive.
·         Services ejecutando onStart, onCreate o onDestroy.
·         Services que han sido marcados como que corren de primera instancia. 
Los Procesos Visibles son visibles, pero inactivos. Estos son poco comunes, suceden cuando una Activity se lanza, y no cubre toda la pantalla o es transparente y muestra la aplicación de fondo. Android solo eliminaría procesos en este estado en casos extremos.
Los Procesos de Servicio son Services que han iniciado, no tienen una interfaz visible, y estan actualmente corriendo de fondo. Son importantes, y solo serán eliminados en el caso que Android requiera recursos para el proceso activo.
Los Procesos de Background no son visibles, y tampoco estan corriendo actualmente. Generalmente hay muchos procesos de fondo que Android matará segun las reglas que tiene definidas.
Los Procesos Vacios son cascarones que permanecen en la memoria aún despues de haber sido cerradas. Permanecen en este estado para agilizar el cargar la aplicación si se vuelve a abrir, y son eliminados en cuanto los recursos se requieren.

Android vs Java


Diferencias con una máquina virtual Java normal

      
 En primer lugar, la máquina virtual de Dalvik (Android) toma los archivos generados por las clases Java y los combina en uno o más archivos ejecutables Dalvik (. dex), los cuales a su vez son comprimidos en un sólo fichero .apk (Android Package) en el dispositivo. De esta forma, reutiliza la información duplicada por múltiples archivos .class, reduciendo así la necesidad de espacio (sin comprimir) a la mitad de lo que ocuparía un archivo .jar. 

        En segundo lugar, Google ha mejorado la recolección de basura en la máquina virtual de Dalvik, pero ha preferido omitir just-in-time (JIT), en esta versión por lo menos. La empresa justifica esta elección diciendo que muchas de las bibliotecas centrales de Android, incluyendo las bibliotecas de gráficos, están implementadas en C y C++. Del mismo modo, Android proporciona una biblioteca de C optimizada para acceder a la base de datos SQLite, pero esta biblioteca está encapsulada en un nivel superior del API de Java. Dado que la mayoría del código del núcleo se encuentra en C y C++, Google argumentó que el impacto de la compilación JIT no sería significativo.

        Por último, la máquina virtual de Dalvik utiliza un tipo diferente de montaje para la generación del código, en el que se utilizan los registros como las unidades primarias de almacenamiento de datos en lugar de la pila. Hay que señalar que el código ejecutable final de Android, como resultado de la máquina virtual de Dalvik, no se basa en el bytecode de Java, sino que se basa en los archivos .dex. Esto significa que no se puede ejecutar directamente el Bytecode de Java, sino que hay que comenzar con los archivos .class de Java y luego convertirlos en archivos .dex.
 Formato de un fichero .dex
 Tras comenzar a estudiar las características de Android, pueden observarse algunos aspectos que, si bien no siempre resultan una ventaja frente a sus competidores, sí son interesantes y pueden repercutir positivamente en su elección como plataforma. Por ejemplo:

Diferencias de arquitectura y Librerias
   
 A pesar de que Google evita usar el término demasiado, el hecho de utilizar un lenguaje tan popular como Java ayuda a que cualquier programador mínimamente experimentado pueda comenzar a programar sus aplicaciones sin mayor complicación, además de animar a los que ya estén muy familiarizados. Incluye, además, las API más importantes de este lenguaje como java.util, java.io o java.net.
  La licencia Apache permite a todo el mundo poder estudiar, modificar y distribuir el sistema Android, a la vez que da opción al desarrollo privado mediante la publicación comercial de aplicaciones. Cada desarrollador puede decidir cómo quiere distribuir su propio trabajo.

Como ya es sabido, Android divide todas sus aplicaciones en componentes o bloques básicos que, combinados, constituyen el programa final. Así, tenemos bloques visibles para el usuario mediante interfaces (Activity), bloques que se ejecutan en background fuera de su conocimiento (Service), bloques a la escucha de determinados eventos (Broadcast Receiver) y bloques que ofrecen contenidos a otras aplicaciones (Content Providers). Esta filosofía es original y ayuda a modularizar funcionalmente las aplicaciones.

·         La delegación de acciones en otras aplicaciones mediante Intents es otro de los aspectos más innovadores ofrecidos por Android. Mediante un Intent, la aplicación simplemente expresa lo que desea hacer y es el sistema el encargado de buscar la aplicación más adecuada (para llamar, mandar un correo electrónico, abrir una página web, etc.). Así mismo, las aplicaciones pueden anunciar a las demás que están preparadas para poder atender determinados tipos de Intents.

·         La construcción de interfaces de usuario ha sido un aspecto muy cuidado, no sólo por la amplia colección de elementos y diseños incorporados, sino por la posibilidad de ser definidas tanto en el código fuente como mediante documentos XML externos.

·         El acceso a los recursos del dispositivo, como GPS, Wi-Fi, etc., se convierte en una tarea fácil y simple gracias a las API del SDK.

·         La declaración y uso de recursos externos, tales como imágenes, cadenas de texto, valores numéricos, o incluso diferentes modelos de interfaz de usuario y de diseños es cómoda y fácil de realizar.
En cuanto a las librerías estas son algunas diferencias:
·         APIS que controlan el ciclo de vida de la aplicación.
·            ANDROID: Principalmente se usan android.app.Activity y android.app.ListActivity. 
·           JAVA: Principalmente se usa javax.microedition.midlet.MIDLET.

·          APIS que definen la interfaz de usuario de la aplicación. 
  Alto Nivel
·              ANDROID: Principalmente se usan android.widget.ArrayAdapter y android.widget.ListAdapter 
·             JAVA: Esencialmente son javax.microedition.lcdui.Display yjavax.microedition.lcdui.Displayable
  Bajo Nivel
·              ANDROID: Principalmente se usan android.graphics.drawable.Drawable y android.view.View
·             JAVA: Esencialmente son javax.microedition.lcdui.game.GameCanvas y javax.microedition.lcdui.Displayable.Canvas
  
·          APIS media: Bluetooth, Multimedia y sensores.
  Bluetooth
·              ANDROID: Android ofrece la siguiente librería para usar esta interfaz, android.bluetooth.
·             JAVA: CLDC tiene un paquete opcional para usar Bluetooth (JSR 82): “Bluetooth API”.
  Multimedia
·              ANDROID: Ofrece la siguiente librería para reproducción de audio y vídeo, android.media: MediaPlayer.
·             JAVA: CLDC ofrece el paquete opcional “MMAPI” y un soporte básico en la API de MIDP 2.0: Manager, Playery Control en los paquetes javax.microedition.media y javax.microedition.media.control.
   Sensores y acelerómetro
·              ANDROID:Android proporciona la clase  android.hardware.SensorManager, la cual sirve  para  manejar el sensor de orientación, y el acelerómetro.
·              JAVA: CLDC tiene un paquete opcional para gestionar los sensores conectados al móvil (JSR 256): “Mobile Sensor API”.

·         Descriptores. 
·              ANDROID: AndroidManifest.xml
 Los componentes que necesita la aplicación se enumeran en un archivo llamado AndroidManifest.xml, el cual es un fichero XML donde se declaran los componentes y cuáles son sus capacidades y requerimientos. 
·              JAVA: Descriptor JAD
  Permite describir las propiedades de la aplicación y los componentes que forman parte de la misma. De esta manera, el AMS (Application Management System) podrá verificar si es posible instalar la aplicación antes de descargarla. Es un fichero de texto con extensión .jad.

  Arquitectura: Ciclo de vida de la aplicación
·          ANDROID: En Android existen 4 grandes bloques de construcción: Activity, Intent, Service y Content Provider, de los cuales, el bloque Activity es el componente más habitual de las aplicaciones para Android, es decir, un componente Activity refleja una determinada actividad llevada a cabo por una aplicación, y que lleva asociada típicamente una ventana o interfaz de usuario. Los cuatro posibles estados que definen su ciclo de vida son: Activa, pausada, parada y reiniciada. 
·         JAVA: La clase encargada del ciclo de vida de una aplicación, es la clase MIDlet, y los métodos que gestionan el ciclo de vida de una aplicación son tres: activa, pausada y destruida.

 Máquina Virtuales: KVM y CVM (Java ME) vs. Dalvik (Android)
·             ANDROID:La JVM que utiliza Android es la máquina virtual DalvikVM. En ella podemos encontrar una gran diferencia con respecto a la máquina virtual Java (JVM), ya que la máquina virtual de Google no está basada en una pila.
·             JAVA: En el perfil MIDP, la JVM es la máquina virtual KVM, la cual es la máquina virtual más pequeña desarrollada por Sun, y se usa con la configuración CLDC. Se trata de una implementación reducida y especialmente orientada a dispositivos con bajas capacidades computacionales y de memoria. 

 Herencia de interfaz ráfica de Java
·            ANDROID: Android hereda las siguientes librerías de Java: 
·           java.awt.font.* Para definir propiedades del estilo y tamaño de la letra. (Subconjunto de J2SE)
·           java.beans.*: Para definir beans con los métodos get y set.(Subconjunto de J2SE)
·           java.io.*: Conexión genérica.
·           java.lang.*  Clases de la VM. (Subconjunto de J2SE)
·           java.math.* Para operaciones matemáticas.
·           java.nio.*  Para definir buffers.
·           java.security.*  Clases para definir  el modelo de seguridad. (Subconjunto de J2SE)
·           java.sql.* API para usar JDBC y gestión de base de datos con SQL.
·           java.text.* Para definir diferentes formatos de texto.
·           java.util.* Clases para utilidades estándar. (Subconjunto de J2SE)
·           javax.crypto.* Clases para realizar operaciones criptográficas.
·           javax.microedition.khronos.* Clases orientadas a diseño de interfaces 3D.
·           javax.net.* Clases para aplicaciones de Red. (Subconjunto de J2SE)
·           javax.xml.* Para usar lenguaje XML en el Descriptor de la aplicación.

·           JAVA:  El perfil MIDP, hereda las siguientes librerías de Java:
·         java.io.* Clases y paquetes estándar de E/S. (Subconjunto de J2SE)
·         java.lang.* Clases e interfaces de la VM. (Subconjunto de J2SE)
·         java.util.* Clases, interfaces y utilidades estándar. (Subconjunto de J2SE)
  Mensajería instantánea: SIP(Java ME) vs. XMPP(Android)
·             ANDROID: Android ofrece una API para desarrollar protocolos de mensajería instantánea, concretamente                         XMPP (Extensible Messaging and Presence Protocol), protocolo de intercambio de mensajes basado en XML.
·             JAVA: Java ME con el perfil MIDP ofrece un paquete opcional para utilizar protocolos de mensajería instantánea, concretamente SIP (Session Initition Protocol).

Almacenamiento de Datos: RMS(Java ME) vs. SQLite(Android)
·              ANDROID: Android ofrece la superclase android.content.ContentProvider para el manejo y almacenamiento de datos, conocido también como “proveedor de contenido”. Este bloque de construcción, permite compartir datos entre procesos y aplicaciones.
 Además, Android soporta BBDD SQLite y proporciona funciones de control que permiten almacenar datos complejos en forma de objeto.
·             JAVA: MIDP ofrece la librería javax.microedition.rms para memoria persistente, lo cual consiste en una base de datos binaria sencilla (sin usar SQL) orientada a almacenes de registros (RecordStore).

 Navegador (Java ME) vs. WebKit (Android)
·            ANDROID: El SO Android dispone de un navegador integrado basado en el motor del proyecto abierto WebKit.
·            JAVA: CLDC ofrece la posibilidad de desarrollar clientes web con “Web Services APIs”.

 Portabilidad de Aplicaciones
·           ANDROID: En este ámbito, Java ME tiene una enorme ventaja sobre Android, ya que tiene una VM “totalmente Java”, mientras que la VMde Google (Dalvik), a pesar de sus grandes ventajas ya comentadas, hace que la migración de una aplicación open-source de Linux x86 sea realmente dura. Todos los interfaces de usuario y la lógica han de ser reescritos desde cero.
·           JAVA: La existencia de diferentes perfiles en Java ME consiguen garantizar la portabilidad de las aplicaciones, que utilizan un API no tan complejo y extenso como en el caso de Android, pero suficiente para que el código sea portable entre diferentes dispositivos móviles.

¿Puede ejecutarse un Proyecto Java ME en un móvil con ANDROID?

·         Claro que si, usando MicroEmu (Emulador de J2ME hecho en Java) o bien con el J2ME MIDP Runner.
Diferencias en aspectos de programación
·         ANDROID: Permite desarrollar aplicaciones en los siguientes entornos de programación: 
         Eclipse
         Netbeans
·         JAVA: Permite desarrollar aplicaciones en los siguientes entornos de programación: 
        J2ME Wireless Toolkit 2.2
        J2ME WTK 2.5
        Java ME Platform SDK 3.0
       Netbeans: Mobility Pack 4.1
                 Eclipse: Plug-in EclipseME

   Midlet(Java ME) vs. Activity(Android)
·         ANDROID:  En Android una pantalla (asociada a una interfaz de usuario) se corresponde
 con la clase Activity, y para pasar de una pantalla a otra se utiliza la clase Intent de
 la siguiente manera:
                          Intent intentLista = new Intent();      intentLista.setClass(Clase1.this,Lista.class);//origen,destino
                                     startActivity(intentList);//para pasar a la pantalla asociada a la clase Lista 
·         JAVA:  En MIDP para pasar de una pantalla otra se utiliza la clase Display de la siguiente
manera:
                                            this.midlet.getDisplay().setCurrent(this.midlet.getLista());
Donde el método getLista() devuelve un objeto del tipo List de la API de alto nivel
 Además, se usa la clase Command para añadir un comando al Displayable y poder cambiar
de una pantalla a otra, utilizando el siguiente método:
                                    addComand(Command)
  Modelo de seguridad
·         ANDROID: En Android se hace en el fichero AndroidManifest.xml. Por ejemplo, si
 queremos acceder a la API de bajo nivel, ActivityManager, para obtener el número
de procesos en ejecución, debemos añadir la siguiente línea al descriptor:
 <uses-permission id="android.permission.GET_TASKS" android:name="GET_TASKS"/> 
·         JAVA:  CLDC sigue el modelo “sandbox” y MIDP 2.0  proporciona un modelo de seguridad
a nivel de aplicaciónmediante firmas digitales que permiten determinar si una aplicación es
 fiable o no asociada a un dominio de seguridad. Las políticas permiten especificar los
permisos asignados a cada dominio. 
 Gestión de eventos (escuchadores)
·          ANDROID: Principalmente se usan android.view.View.OnClickListener
 (para capturar el evento OnClick de cualquier elemento del Layout, por ejemplo un botón) y android.view.MenuItem.onMenuItemSelected (cuando se usa la tecla Menú
para interactuar con el usuario, para capturar el evento OnClick de una de las
opciones del menú).
·         JAVA: Sigue el modelo de manejo de eventos y escuchadores definidos en Java SE,
así tenemos fuentes de eventos que mantiene escuchadores que están interesados en saber cuándo ocurre un evento y proporciona métodos que permite que los escuchadores se añadan a dicha lista. Así cuando la fuente genera un evento, se lo notifica al escuchador correspondiente para que procese el evento, ejecutando la acción programada. Además, con la API de bajo nivel se pueden programas eventos del teclado y puntero. Por ejemplo, en la clase javax.microedition.lcdui.game.GameCanvas se gestionan los eventos de teclado por polling utilizando el método getKeyStates(). 
  Propiedades del sistema
·         ANDROID: Las propiedades del sistema se definen en el fichero AndroidManifest.xml, el cual describe la aplicación, los permisos necesarios, etc… Todos los proyectos Android tienen este archivo que, entre otras cosas, nos dará la posibilidad depedir los permisos que vayamos necesitando, y definirá la actividad inicial que se ejecutará. 
·         JAVA: Las propiedades del sistema se definen en el fichero descriptor de la aplicación (JAD) y se obtienen viajava.lang.System y javax.microedition.MIDlet, por ejemplo:
                        System.getproperty(String key)

   Uso de memoria
·         ANDROID: En este aspecto Android es el ganador ya que los terminales Android no imponen restricciones de memoria, debido a que cada aplicación Android corre su propio proceso, con su propia instancia de la VM Dalvik. Dalvik permite el uso eficiente de dichas instancias. Ejecuta ficheros en el formato .dex optimizado para el consumo mínimo de memoria. 
·         JAVA: Los sistemas J2ME tienen restricciones importantes de memoria para el almacenamiento y ejecución de aplicaciones, restricciones por debajo de 50K.

  Uso de hilos (contextos)
·         ANDROID:  Ofrece el paquete java.util.concurrent, heredado de java, y android.os para mecanismos de sincronización de procesos, tareas, hilos y actividades. 
·            La principal diferencia entre las dos tecnologías es que Android ofrece un “entorno multitarea”, es decir, cada aplicaciónde Android corre en su propio proceso, el cual es creado por la aplicación cuando se ejecuta y permanece hasta que la aplicación deja de trabajar o el sistema necesita memoria para otras aplicaciones. Una característica fundamental de Android es que el ciclo de vida de una aplicación  no está controlado por la misma aplicación sino que lo determina el sistema a partir de una combinación de estados como pueden ser que aplicaciones están funcionando, que prioridad tienen para el usuario y cuanta memoria queda disponible en el sistema. De esta manera,  Android sitúa cada proceso en una jerarquía de "importancia", concretamente sigue el estándar POSIX, de modo que la política de eliminación de procesos esTRANSPARENTE para el programador, ya que la capa inferior de la plataforma está compuesta por un núcleo Linux (versión 2.6) que se usa como capa de abstracción de hardware (HAL, Hardware Abstraction Layer). Si el programador desea ver los procesos en ejecución a bajo nivel, la única posibilidad es usar la herramienta AIDL, la cual ofrece al programador la visualización de las llamadas del SO a los métodos IPC.
·         JAVA: Java ME, al igual que Android ofrece un entorno “multithreaded”, ya que permite realizar múltiples actividades simultáneamente, pero se diferencia en que el Planificador de hilos (el cambio de contexto) no lo puede controlar el programador sino que puede suceder en cualquier momento. Aún así, existen “trucos” para que el programador sea capaz de gestionar varios hilos dentro de una misma aplicación.


Finalmente el proyecto de como seria un HELLO WORD en las dos tecnologias:
Android:


Java: