domingo, 30 de diciembre de 2012

Feliz Año 2013

Hola a todos,

Debido a que no se cual será mi estado etílico mañana :D os felicito ya por adelantado el año.

Es el segundo fin de año que felicito por el blog (quien me iba a decir que iba a aguantar más de un año todo este tinglado) y la verdad que estoy muy contento tanto de la gente que he ido conociendo por mail como de todo lo que he ido aprendiendo o redescubriendo para poderoslo explicar.

Este año, además, lo despido con la alegría de haber llegado este mes, por primera vez, a las 10.000 visitas mensuales (si lo se, no es mucho, pero para el tiempo que puedo dedicar para mi ya es un motivo de satisfacción)

A modo de curiosidad, os dejo los temas que más se han visto hasta ahora en el blog:
Tutorial de programación
LordPakus Game Engine
Curso de electrónica
Referencias de programación
Tutorial de ensamblador x86

Espero que el próximo año este cargado de nuevos temas y tutoriales y que me vayáis proponiendo de que queréis que hable

Ya por finalizar solo puedo deciros.. GRACIAS Y FELIZ AÑO 2013

domingo, 16 de diciembre de 2012

Curso de electrónica: Capitulo 5. Circuitos digitales complejos sin memoria (ALU)



Hola a todos,

Ya hemos visto circuitos sencillos con y sin memoria, pero con lo que hemos visto ni nos acercamos a lo que sería un procesador.

El tema de hoy es uno de los circuitos sin memoria más complejo que existe, la ALU (Unidad Aritmetico Lógica)

Una ALU no es más que un conjunto de operaciones digitales seleccionables (mirar el capitulo del multiplexor) realizadas mediante puertas lógicas. Es algo así como una librería de programación pero hecha a nivel de electrónica.


A y B son los operandos. Por ejemplo dos números que queramos sumar.
F es la selección de la función que queremos implementar. Por ejemplo, sumar.
R es el resultado de la operación
D son los flags de estado de la operación: Problemas que pueda haber en la operación, si el resultado es 0, etc...

Como está hecha una ALU a nivel de puertas lógicas?
Este es un ejemplo muy muy sencillo de como se podría hacer un ALU de lo más sencillo posible.

Como se une la ALU al resto del procesador?
Aunque esto sea tema para otro artículo, solo diré que la ALU, para funcionar , necesita de otros elementos digitales para poder funcionar, principalmente, memorias. No os preocupéis que esto lo iremos mirando con más tranquilidad en próximos capítulos.


 Cuantas más operaciones nos permita hacer la ALU más compleja será esta y más versatilidad tendrá. Para que os hagáis una idea, la ALU que podría tener un despertador no le haría falta mucho más que un par de operaciones ( sumar y comparar) mientras que la ALU del procesador de vuestro ordenador de bien seguro que tiene más de 1000 operaciones.

Aunque se que este capitulo es corto y denso no os desanimeis que nos es necesario para poder avanzar en cosas más interesantes.

Espero que os haya gustado.

LordPakusBlog

domingo, 2 de diciembre de 2012

Curso de programación: Capitulo 13. Parámetros por linea de comandos


Hola a todos,

Cuando llamamos a un programa cualquiera desde linea de comandos normalmente este acepta diversos parámetros que nos permiten configurar el comportamiento deseado. Un ejemplo lo tenéis aquí

La gran pregunta es... y como lo hacemos nosotros en nuestros programas??

La forma estandarizada es mediante argc y argv.  argc es el número de parámetros que nos pasarán y argv un vector de cadenas de texto con todos los parámetros.


int main(int argc, char *argv[])

argc siempre será el número de parámetros de entrada +1 y argv[0] será el nombre del programa, así, aunque al programa no le pasemos parámetros siempre recibirá un parámetro que será su propio nombre.

Aquí tenéis un ejemplo para que veáis como funciona:

int main(int argc, char *argv[])
{
  if (argc == 1)
  {
      cout << "haga /h para ver el help" << endl;
      return 0;
  }
  if( argc == 2)
  {
      cout << argv[1] << endl;
      return 0;
  }

  cout << "Número de parámetros excesivos" << endl;
  return 0;
}


Espero que os sirva y podáis sacarle provecho.

Nos vemos

LordPakusBlog

domingo, 25 de noviembre de 2012

Tutorial de ensamblador x86. Capítulo 3. Primeras optimizaciones



Hola a todos,

Si habéis ido siguiendo el curso, y habéis mirado los ejemplos, lo más normal es que hayáis intentado programar alguna cosilla en asm. Y también lo más normal es que toda vuestra ilusión se haya ido al garete al ver que el rendimiento de vuestra aplicación más que mejorar , empeora.

Si vuestra aplicación pierde rendimiento al aplicarle ensamblador es por el sencillo motivo que el compilador sabe "compilar" un poco mejor que vosotros :D y tiene muy claras las normas de lo que se puede hacer y lo que no se puede hacer.

Os presento ahora la lista con las cosas más típicas que se pueden mejorar en vuestra aplicación y ya veréis como poco a poco el rendimiento os irá mejorando.

1. Dependencias de datos: Esta es la más típica y normalmente la que menos se puede solucionar. Cuando nosotros ejecutamos una instrucción en ensamblador el procesador realmente lo que hace es intentar adelantarse a los acontecimientos e ir ejecutando la parte que pueda de la siguiente instrucción (si queréis saber más tendréis que googlear un poco sobre segmentación de CPU y pipeline, pero no es fácil de entender de buenas a primeras). Si nosotros encadenamos dos funciones seguidas en que el resultado de la primera forma parte de los operandos de la segunda ya no podemos ir adelantando trabajo, haciendo que el rendimiento del procesador  disminuya drásticamente. La solución se basa en intercalar otras operaciones con otros operandos en medio de las zonas conflictivas a fin de que el procesador pueda ir adelantando trabajo de otras operaciones. El problema de hacer esto es que el código queda desordenado y es de difícil comprensión.

2. Saltos condicionales: Cada vez que vamos ha hacer un salto de código (jmp, je, jg , jl) el procesador intenta adivinar que será lo más probable y ya lo empieza a precalcular. Esto significa que hay un cierto número  de veces que el procesador hará trabajo por que si, ya que la comparación no será como el se esperaba. Hay casos en que el circuito que se encarga de preveer por donde irá nuestro código falla bastante y es extremadamente complejo de predecir, así que el único consejo que os puedo dar es que minimicéis el número de saltos en la medida de lo posible.

3. Acceso a memoria: Da igual que memoria tengáis o cuan cara y rápida sea, minimizad los accesos a memoria. Acceder a un registro cuesta 1 o 2 ciclos de reloj. Acceder a memoria pueden llegar a ser cientos de ciclos. Así pues, es sencillo. Aprovechad los registros, y haced un poco de trileros con los registros para que los valores que hayamos leído una vez no los tengamos que leer otra vez.  Solo con esta optimización podéis llegar a multiplicar x10 o x20 el rendimiento de vuestra aplicación.

4. Usad trucos de asm: El lenguaje ensamblador lleva décadas usándose normalmente en plataformas muy justas de recursos. Esto ha llegado a desarrollar unos trucos que nos permitirán arañar ciclos de reloj cuando pensemos que ya no podemos hacer nada más.
 - Usad xor eax,eax  en vez de mov eax,0. Hace lo mismo y es más rápido. La operación xor de una variable con ella misma siempre es 0.
- Usad desplazamientos de bits en vez de multiplicaciones o divisiones con múltiplos de dos:
   shr ecx, 1   es lo mismo que ecx /= 2 pero muchísimo más rápido
   shl eax,2 es lo mismo que eax *= 4 pero muchisimo más rápido.

5. Usad instrucciones especificas para problemas específicos: Los compiladores de C ,normalmente, usan solamente unas 20 instrucciones de ensamblador para hacerlo todo. Esto es debido a la gran complejidad del proceso de compilación, pero realmente los procesadores poseen centenares de instrucciones. Ejemplos lo tenéis a cientos, una instrucción como bswap te permite hacer en un solo ciclo el trabajo que se podría hacer en decenas de ciclos. y las instrucciones de SSE te permiten trabajar con 4 ints a la vez aplicando funcionalidades que tal vez no habías ni imaginado. Tendréis que investigar pero ya veréis que con el suficiente tiempo dedicado podréis encontrar alguna instrucción que os resulte extremadamente útil en vuestra aplicación.

Y con esto acaban los consejos básicos para optimizar vuestro código ensamblador.

Espero que os haya gustado,

Nos vemos

LordPakusBlog

Tutorial de ensamblador x86. Capítulo 2. Conceptos básicos



Hola  a todos,

A partir de este capítulo espero que podáis hacer vuestras primeras funciones en ensamblador, y nos servirá de base para poder ir avanzando en conceptos un poco más peliagudos.

El código en ensamblador (como la mayoría de los lenguajes de programación) se basa en la ejecución de las instrucciones que queremos realizar sobre los datos que nos interesa modificar. Estos datos están almacenados en los registros.


Registros

Los registros son trozos  de memoria parecida a la RAM muy pequeña y muy muy rápida que están incrustados dentro del mismo procesador, por lo tanto, la forma de acceder y trabajar con ellos es particular de ese procesador.

Registros de 32 bits: Los registros de 32 bits son los más usuales y son los que nos permiten almacenar  1 int,  1 floats, 2 shorts o 4 chars.

Aunque hay bastantes registros internos, los que podemos usar desde programación son 6: eax, ebx, ecx, edx, esi, edi.

Aquí es donde se ha de ir con cuidado, hay registros con funcionalidades muy concretas y hay funciones que usaran ciertos registros sin previo aviso.

Ejemplos:
- La función de multiplicación acepta solo un parámetro, Este parámetro lo multiplicará por lo que haya en eax y el resultado lo dejará en eax y edx (la multiplicación de dos números de 32 bis puede ocupar 64 bits). Es decir, que después de usar la multiplicación eax y edx valdrán lo que ella quiera que valga no lo que nosotros teníamos almacenado.
- Las funciones de movimieno de string (movsd por ejemplo) usan de forma implicita los registros esi (source, origen) y edi (destination, destino) para apuntar a las zonas de memoria de origen y destino donde se hace la copia.
- La función ret (la que es comparable al return de C) no pide parámetros (al menos para el nivel que a nosotros nos interesa ), así que el valor de retorno de la función lo obtiene del registro eax de forma implicita.
- La función loop solo admite como parámetro el label de a donde tenemos que saltar. El contador de bucle es de forma implícita ecx.

Registros de 16 bits: A veces nos hace falta trabajar con 16 bits. Los registros de 16 bits de los que disponemos no son más que los 16 bits de menor peso de los registros anteriores, que son: ax, bx, cx, dx, si, di.

Registros de 8 bits: En ocasiones, 16 bits no es suficientemente pequeño y hemos usar registros del tamaño de 1 byte. Para estas ocasiones tenemos la opción de usar los bytes de los registros de 16 bits por separado: ax = al + ah, bx = bl + bh, cx = cl + ch, dx = dl + dh.

A nivel gráfico se podría resumir tal que así:



Operaciones:
Las instrucciones en ensamblador pueden aceptar un número variable de parámetros en función que operación sea (y en ocasiones una instrucción tiene diferentes usos en función de los parámetros que se le pasen)
Ya que hay cientos de funciones y todas ellas tienen sus particularidades vamos a explicar como funcionan poniendo ejemplos:

char LP_memcmp( const void * ptr1, const void * ptr2, size_t num )  //Cabecera de función en C
{
__asm   //Le decimos al compilador que vamos a iniciar un trozo de código en ensamblador
{
mov ecx,num //Movemos lo que tenemos en la variable num, dentro del registro ecx
mov esi,ptr1  //Movemos lo que tenemos en la variable ptr1, dentro del registro esi
mov edi,ptr2  //Movemos lo que tenemos en la variable ptr2, dentro del registro edi

....


no_multiplo:        //Etiqueta usada por las instrucciones de salto
dec ecx               // Decrementamos en una unidad el valor de ecx
mov al,[esi]        //Copiamos al subregistro  al el byte de memoria al que apunta el registro esi (es un                    puntero)

.....


cmp eax,ebx   //Compara el valor de eax con ebx
jg mayor          //Salta a la etiqueta "mayor" si eax es mayor que ebx
jl menor           //Salta a la etiqueta "menor" si eax es menor que ebx



Con todo lo que os he explicado y los ejemplos que he ido colgando deberíais ser capaces de empezar ha hacer vuestras primeras funciones. Para cualquier duda no dudéis en consultármela.

Nos vemos



LordPakusBlog




sábado, 24 de noviembre de 2012

Lista de instrucciones de ensamblador ASMx86 más usadas.

Artículo perteneciente al curso de ensamblador

Este artículo está íntimamente relacionado con "Referencias de programación"

Aquí os dejo las instrucciones de ensamblador más usuales en procesadores x86.

Movimiento de Datos:
mov: Movimiento de datos: Funciona entre dos registros o entre memoria y registro (y viceversa). Mueve un dato del tamaño del registro implicado de un lugar a otro. En C sería equivalente a la "instrucción" =. (a = b)
Ejemplos:
mov al,[esi]    mov ecx,num    mov eax, -1

bswap: Binary swap Invierte los bytes de un int. El primer byte lo intercambia con el cuarto y el segundo con el tercerto. Muy útil para trasnformaciones de litle-big endian.

shr: Shift right. Desplazamiento binario a la derecha de x posiciones. Equivalente en C a >>
shl: Shift left. Desplazamiento binario a la izquierda de x posiciones. Equivalente en C a <<


Operaciones lógicas:

and: Realiza la operación lógica "y" entre los dos operandos. Si queréis saber algo más de la operación lógica "y" podéis mirar este link

xor: Realiza la operación lógica "suma exclusiva" entre los dos operandos. Si queréis saber algo más de la operación lógica xor podéis mirar este link


Operaciones aritméticas:
inc:  Incrementa en un unidad el valor del registro que se le pase.(equivalente en C a ++)

dec:  Decrementa en un unidad el valor del registro que se le pase. (equivalente en C a --)

add: Suma dos registros y guarda el resultado en el primero. (equivalente en C a +=)

sub: Resta dos registros y guarda el resultado en el primero. ( equivalente en C a -=)


Comparaciones:
cmp: Compara dos registros y setea los flags para que después se puedan hacer saltos condicionales(jz, jnz, jg,etc...) (equivalente en C a if)

test: Aplica la operación and entre dos registros, pero sin poner el valor del resultado, solo preparando los flags para que después se pueden realizar los saltos condicionales.

jz: Jump Zero. Salto condicional. Salta a la etiqueta que se le diga si la comparación anterior daba 0.

jnz: Jump No Zero. Salto condicional. Salta a la etiqueta que se le diga si la comparación anterior daba diferente de 0.

jg: Jump Greater. Salto condicional. Salta a la etiqueta que se le diga si la comparación anterior daba que el primer elemento era mayor.

je: Jump Equal. Salto condicional. Salta a la etiqueta que se le diga si la comparación anterior daba que los dos registros eran iguales.

jne: Jump No Equal. Salto condicional. Salta a la etiqueta que se le diga si la comparación anterior daba que los dos registros no eran iguales.


Otras:
jmp: Operación de salto. La ejecución de código continua en la etiqueta que se le pase como parámetro. ( equivalente en C al poco recomendable goto)

loop: Mientras que en el registro ecx tenga un valor diferente de 0, decrementa ecx y salta a la etiqueta que se le diga. Muy util para realizar bucle. Equivalente en C a while( (ecx--) > 0 ) {}

leave: Limpia todo lo que hayamos tocado en la función en la que estamos para que podamos volver a la  función que nos ha llamado sin afectar al programa. Siempre se llama antes de hacer un ret

ret: Retorno de función. Equivalente al return de C




 A medida que vaya desarrollando el curso y poniendo más ejemplos iré rellenando esta lista. Si creéis que falta alguna instrucción importante decirlo.

P.D: Si quereis también podeis mirar la siguiente lista que os podrá ayudar en vuestro estudio del ensamblador

LordPakusBlog


Tutorial de ensamblador x86. Capítulo 1. Introducción al ensamblador



Hola a todos,

Bienvenidos a este primer capítulo del tutorial de ensamblador. Antes que nada, deberíamos ponernos en situación

Que es el ensamblador?
El lenguaje ensamblador es el lenguaje de programación más parecido al que utiliza nuestro procesador, permitiéndonos ejecutar programas en  dicho procesador como nosotros queremos.
Los diferentes lenguajes  compilados ( C,C++, Fortran, etc...) realmente lo que hacen es pasarse a ensamblador para que el compilador pueda ejecutarlos.

Por que usar ensamblador?
El motivo más claro para usar ensamblador es el aumento de rendimiento de nuestras aplicaciones. Al usar las instrucciones de ensamblador como nosotros queremos podemos desarrollar códigos óptimos que realicen tareas varios ordenes de magnitud más rápidas que con lenguajes compilados. Esto es así por que los compiladores (los programas que se encargan de "traducir" código C ,por ejemplo) a ensamblador no son perfectos, ni pueden serlo debido a la alta complejidad de las casuísticas posibles y usan los recursos de nuestro procesador de forma subóptima.

Por que no se usa más el ensamblador?
Si el ensamblador es tan bueno, se hace complicado entender por que no se usa en todos los ámbitos de la programación, la respuesta es sencilla: la complejidad. El código escrito en ensamblador tranquilamente es 10 (o 100 ) veces más largo en extensión de lineas de código que un programa en C, aparte de que es más complejo entenderlo, debugarlo y en general desarrollar sobre este lenguaje directamente.

Como se puede usar el lenguaje ensamblador?
Hay dos maneras básicas de usar el ensamblador, una es usando directamente un programa ensamblador que nos pase nuestro código .asm a .exe o .o o lo que toque (como un compilador de C/C++). La otra manera (que es la única que uso y que explicaré) es mediante ensamblador inline. La mayoria de los compiladores actuales permiten introducir trozos de ensamblador dentro del código C/C++, permitiendo usar el ensamblador solamente para aquellas funcionalidades que realmente comprometen el rendimiento total de la aplicación. Es una manera limpia y bastante mantenible de introducir ensamblador en nuestros programas.

Como introduzco código ensamblador en mis programas de C?
He aquí el gran problema del ensamblador inline, no está estandarizado. Esto quiere decir que cada compilador tiene potestad para hacer un poco lo que quiera. Gcc usa un estandar que no me gusta demasiado(algo malo debería tener :D ) ,  DevCpp lo mediosigue, WatCom (un compilador bastante antiguo) tiene su forma muy particular de decidir que registros se pueden modificar o no y de linkar los parametros de entrada de las funciones con los registros del compilador, pero sin duda, para mi el mejor sistema de ensamblador inline es el MSVC++ (lo podéis encontrar en versión gratuita). Este sistema es el que usaré para todos los ejemplos. Si alguien tiene problemas en su compilador que me lo diga y le buscaremos una solución.

La forma de introducir código ensamblador inline es visual studio (MSVC) es tan tonta como la siguiente (solo es un ejemplo):

Código en C


__asm
{
mov ecx,num
mov edi,destination
mov esi,source

shr ecx,2

rep movsd

leave
ret
}


Código en C

En breve os pasaré una lista con las instrucciones más típicas y empezaremos el curso de ensamblador como tal.

Espero que os guste.


Nos vemos


LordPakusBlog

domingo, 18 de noviembre de 2012

LP_memDif. Fast memdif: memdif rápido en asm x86

Articulo íntimamente relacionado con el curso de ensamblador

Este artículo proviene de una mejora del memcmp en ensamblador

Hola a todos,

Hay bastantes ocasiones en que usamos el memcmp solamente para saber si dos trozos de memoria son iguales o diferentes , sin importarnos demasiado en que bit se diferencian ni ningún tipo de información adicional.

Es por ello que he desarrollado esta nueva funcionalidad memDif  basándome en mi implementación en asm del memcmp.

Probadlo a ver como os va, la filosofia es la misma que la del memcmp: 0- los dos trozos de memoria son iguales, otro valor- son diferentes.

A nivel de rendimiento va el doble de rápido que el memcmp de C estándar (que no es poco) y espero que os pueda servir en vuestras aplicaciones cuyo rendimiento dependa de la comparación de zonas de memoria.

Aquí os dejo el código:


char LP_memDif( const void * ptr1, const void * ptr2, size_t num )
{
__asm
{
mov ecx,num
mov esi,ptr1
mov edi,ptr2

test ecx,3
jz multiplo4

xor eax,eax
xor ebx,ebx
no_multiplo:
dec ecx
mov al,[esi]
mov bl,[edi]
xor eax,ebx
jnz fin
inc esi
inc edi

and ecx,ecx
jz fin

test ecx,3
jnz no_multiplo

multiplo4:
shr ecx,2

bucle:
mov eax,[esi]
mov ebx,[edi]
add esi,4
add edi,4

xor eax,ebx
jnz fin
    loop bucle

fin:
leave
ret

}
}

Espero que os haya gustado.

Nos vemos


LordPakusBlog

LP_memcmp. Fast memcmp: memcmp rápido en asm x86

Articulo íntimamente relacionado con el curso de ensamblador

Hola a todos,

La libreria stdlib.h de C da muchas funcionalidades con un rendimiento impresionante (memcmp y memcpy tiene una velocidad espectacular), pero incluso así son mejorables y en algunos casos las características de nuestro software nos obligan a optimizarlas.

La implementación del memcmp de C está hecha byte a byte por temas de compatibilidad con las diferentes plataformas existentes, pero realmente, si optimizamos para la plataforma x86 (que es de largo la más usada en los hogares de todo el mundo) podemos obtener grandes beneficios de usar 32 bits en vez de 8.

En nuestro caso concreto , los 32 bits se usan para poder comparar 4 bytes a la vez, reduciendo los accesos a memoria y el tiempo de cálculo. La interfície de parámetros es exactamente la misma que la que se usa para el memcmp de stdlib, así que podréis substituir rápidamente las llamadas para probar su funcionamiento.

Espero que os guste:



char LP_memcmp( const void * ptr1, const void * ptr2, size_t num )
{
__asm
{
mov ecx,num
mov esi,ptr1
mov edi,ptr2

test ecx,3
jz multiplo4

xor eax,eax
xor ebx,ebx

no_multiplo:
dec ecx
mov al,[esi]
mov bl,[edi]
inc esi
inc edi
cmp eax,ebx
jg mayor
jl menor

and ecx,ecx
jz igual

test ecx,3
jnz no_multiplo

multiplo4:
shr ecx,2
bucle:
mov eax,[esi]
mov ebx,[edi]

bswap eax
bswap ebx

add esi,4
add edi,4

cmp eax,ebx

jg mayor
jl menor
loop bucle

igual:
xor eax,eax
leave
ret
mayor:
mov eax,1
leave
ret

menor:
mov eax, -1
leave
ret
}
}



 La función ha sido probada para bastantes casos y parece que su funcionalidad es la correcta y el tiempo de ejecución es un 25% más rápido. 

Si este rendimiento no os es suficiente siempre podéis mirar el siguiente link para conseguir algo más de  rendimiento en vuestro memcmp

A ver si os animáis a probarla en vuestras aplicaciones y me contáis que mejora de velocidad observáis.

Nos vemos.

LordPakusBlog

domingo, 11 de noviembre de 2012

Datahsheets Familia Lógica 74XX


Hola a todos,

Cuando empecé a jugar con la electrónica internet  no estaba ni en pañales practicamente, así que acceder a la información de los componentes era bastante complicado. Como compraríais componentes electrónicos sino sabéis ni como pedirlos?? No podéis ir  a la tienda de electrónica y pedir 100 gramos de puertas AND ni media docena de puertas XOR. De hecho, no puedes pedir ni tan siquiera "un chip con 4 OR's de 2 entradas". Para todo ello se ha de usar la numeración de los chips que nos proporciona el fabricante.

Hay muchos fabricante de chips, los que os pongo a continuación son solamente los que mas accesible tienen su web.

Fabricantes:
FAIRCHILD Semiconductor
Texas Instruments
ST Microelectronics
ON Semiconductor

Si accedéis a estas webs y buscáis un poco encontrareis los datasheets. Un datasheet no es más que un pdf que nos da el fabricante con toda la información que el considera necesaria para que nosotros podamos diseñar nuestro circuito y después comparle los chips. Es bastante útil que vayáis leyendo alguno si nunca lo habéis hecho.

Aparte de eso, hay un estándar en cuanto a la numeración de chips de puertas lógicas, lo que se conoce como familias lógicas. En nuestro caso nos centraremos en la familia 74XX.  Vereis que para cada modelo de puerta hay un número genérico para todas (7400 por ejemplo), pero que después cada fabricante le incluye todos los identificadores que considera necesarios para diferenciar sus características respecto a la competencia.

Os dejo la lista de datasheets:

7400: Puertas NAND de 2 entradas.
FairChild
Texas Instruments
ST Microelectronics
ON Semiconductor

7408: Puertas AND de 2 entradas
FairChild   
Texas Instruments
ST Microelectronics
ON Semiconductor  

7432: Puertas OR de 2 entradas
FairChild    
Texas Instruments
ST Microelectronics
ON Semiconductor

7402: Puertas NOR de 2 entradas
FairChild
Texas Instruments
ST Microelectronics

7486: Puertas XOR de 2 entradas
FairChild   
Texas Instruments
ST Microelectronics
ON Semiconductor

74266: Puertas XNOR de 2 entradas
Texas Instruments


Si algún fabricante no aparece para algún modelo es que o bien no he sabido encontrar el datasheet  o bien ese fabricante no produce ese modelo.

Espero que os sirva, para cualquier duda ya lo sabeís.

Nos vemos

LordPakusBlog

sábado, 10 de noviembre de 2012

Curso de electrónica: Capitulo 4. Circuitos digitales con memoria




Hola a todos...

Hasta ahora todo lo que os he enseñado son circuitos que dada una entrada, dan una salida, pero como todos comprenderéis con esto no se podría hacer un PC.

Para realizar circuitos de dimensiones grandes o de una cierta complejidad se ha de tener un mínimo de capacidad de recordar que ha pasado antes.

Los circuitos que almacenan información más usuales son:

Contadores
Un contador no es más que un dispositivo que se encarga de ir contando cuantos pulsos a tenido en su entrada. En principio no tendría mucha más utilidad que la que podría tener en algún que otro circuito concreto pero realmente es de gran utilidad en los procesadores. Cuando llegue el momento ya os lo explicaré con más precisión.

El esquema de un contador es más o menos el siguiente:
Vcc y GND: alimentación del circuito
A,B,C y D son el valor inicial con el que queremos cargar el contador
Load: Es la señal que indica que se ha de cargar A,B,C y D dentro del contador
Clear : Es la señal que indica que el contador se ha de poner a 0.
Carry y Borrow: Se usan para conectar diferentes contadores en cascada.
Qa,Qb,Qc y Qd son lel valor de cuanto vale el conador en ese momento.
Down y Up: Son las señales para incrementar o decrementar el valor del contador.

Memorias
Como todo el mundo sabe, las memorias son dispositivos para almacenar datos. Se pueden implementar mediante puertas lógicas, pero actualmente se desarrollan directamente con 1 transistor (es complicado de explicar), así que no tiene mucho sentido que le demos vueltas a como están hechas sino a cual es su funcionamiento.
Una memoria típica tiene las siguientes conexiones:

- Una entrada para habilitarnos el funcionamiento del chip (CE: Chip Enable o CS: Chip Select)
- Otra para decirnos si vamos a leer o escribir (R/W)
- Opcionalmente pueden tener una entrada para permitir la salida de datos (OE: Output enable). normalmente es donde conectaremos el reloj del sistema para tener nuestro diseño sincronizado.
- Un conjunto de bits de entrada sirven para decir en que dirección de memoria vamos a guardar o leer el valor en concreto que nos interesa (A0..A13)
- Un  conjunto de bits que conformarán el valor que vamos a grabar en memoria (si ello es necesario) (D0..D7)
- En estos bits D0..D7 nos devolverá el valor almacenado en la dirección que le hayamos proporcionado si era una operación de lectura.

A este esquema de funcionamiento responde tanto la RAM de nuestro PC como los registros internos de nuestro procesador

Espero que os haya gustado. En breves capítulos comenzaremos a unir conceptos de los diferentes capítulos para que veáis todo lo que se puede hacer.

Nos vemos

LordPakusBlog

viernes, 2 de noviembre de 2012

Macros predefinidas estándar de C

Este artículo pertenece a Referencias de programación

Está intimamente ligado a éste articulo

Las macros predefinidas por el compilador son un conjunto de defines usables en nuestros programas que nos proporcionan información interesante del entorno y del momento de compilación o bien de características del mismo código.

Aquí tenéis la lista de macros:

Macros estandar:

__FILE__ : Nos dice en que fichero de código estamos.
__LINE__ : Nos dice en que linea del código estamos.
__DATE__: Nos dice la fecha en la que se realizó la compilación
__TIME__: Nos dice la hora a la que se realizó la compilación.
__TIMESTAMP__: Nos dice la fecha y la hora de la compilación.

Macros no estandar (funcionan en gcc y algunas en MSVC):
__FUNCTION__ : Nos dice en que función estamos.  __func__ existe en C99.
__STDC__ : Nos dice si el compilador es estandar o no.
__STDC_VERSION__: Nos dice la versión del compilador.
__STDC_HOSTED__: El compilador cumple con todas las librerias estandar.
__cplusplus : El compilador acepta c++
__OBJC__ : El compilador acepta objective-c
__ASSEMBLER__ : El compilador acepta ensamblador.

Macros de VisualStudio:
_ATL_VER : Versión de ATL
_CHAR_UNSIGNED : Nos dice si el tipo char es unsigned por defecto o no.
__COUNTER__ : Contador de compilaciones
_DEBUG: Se activa si estamos compilando en modo debug
__FUNCTION__ ,__FUNCDNAME__, __FUNCSIG__ : Nos dan información de la función desde donde llamamos a la macro.
_WIN32 : Está definido para aplicaciones de 32 y 64 bits
_WIN64 : Está definido para aplicaciones de 64 bits.

Hay algunas macros que no he puesto ya que son complejas de entender, de explicar y de usar, pero su aplicación real es anecdótica, así que no nos debería afectar.

Espero que os haya gustado.

Nos vemos




jueves, 1 de noviembre de 2012

Tutorial de programación C/C++ desde 0. Capitulo 12

Hola a todos,

Si habéis estado siguiendo todo el tutorial ya sois capaces de entender código y de comenzar a picar vuestros programas , cada vez un poco más complejos.

Así pues, os puede comenzar ha hacer falta alguna manera para tracear vuestro código y encontrar los fallos que os vayan surgiendo. Para ello usaremos las "macros estandar predefiinidas", es decir, defines que podemos usar para dar más funcionalidad al código.

Aquí os dejo el código de ejemplo, es bastante sencillo:



#include <stdio.h>
#include <stdlib.h>

#define TRAZA printf("%s %d\n",__FILE__,__LINE__)
void function2(int b)
{
TRAZA;
printf("Funcion2: %d\n",b);
}

void function1(int a)
{
TRAZA;
printf("Funcion1: %d\n",a);
}

void main()
{
function1(3);
function2(5);
system("pause");
}

Y aquí una foto del resultado:

Las macros __FILE__ y __LINE__ las rellena el precompilador antes de generarse la compilación, es decir, nos substituye estas macros por el fichero y la linea en la que nos encontramos en ese momento.

Esto es extremadamente útil si queremos realizar alguna funcionalidad de debug (buscar errores) o profiling (mejorar velocidad).

La macro que nos pone  la función en la que  estamos, sería todavía más útil  pero no es estándar para todos los compiladores, así que no lo pondré aquí.

Espero que os haya gustado

Nos vemos

LordPakusBlog

martes, 30 de octubre de 2012

SEO: Como conseguir más tráfico web



Articulo relacionado con el curso de SEO LordPakus

Hola a todos,

Hace un tiempo, aquí,  os dije que tuvierais paciencia y que si ibais publicando poco a poco tendríais mas público, pero por lo visto hay mas de uno que es bastante impaciente y me pide soluciones algo más rápidas :D.

El post de SEO de hoy trata de sobre clasificar los post que hacemos y los medios por los que los comunicamos a nuestros lectores a fin de conseguir optimizar nuestro esfuerzo y conseguir alguna visita adicional.

Todo lo que os explicaré hoy es en gran parte cosecha propia, así que tampoco os lo toméis como una verdad universal sino como una experiencia personal que en mi caso funciona.

Clasificación de los posts:
El gran problema de los post es que a priori es muy difícil predecir como se comportarán, pero si que es cierto que con un poco de experiencia puedes imaginar por donde irán los tiros y actuar en consecuencia.

- Inútiles: Son aquellos posts que realmente no sirven para nada. No te dan tráfico ni a corto ni a medio-largo plazo (es más, hasta te lo quitan). A la que detectéis uno de estos, aprended y no volváis a publicar nada parecido. No tienen por que estar mal escritos , ni poco trabajados, sencillamente, esa temática o esa forma de abordarla no gusta a tu público y puede llegar a dejar de leerte.

- Explosivos: Son aquellos posts que te pueden generar un burrada de tráfico en poco tiempo, pero que en ese mismo poco tiempo desaparecen para el usuario. Normalmente son posts con un alto porcentaje de imágenes de temas que afectan a la emoción del público (humor, rabia, solidaridad,etc...). Si orientáis vuestro web/blog a este tipo de contenidos podréis tener muchísimo tráfico, pero tendréis que estar publicando sin parar para no quedaros sin público.

- Vacas Lecheras: Son aquellos posts que al principio pasan más o menos desapercibidos o con un ligero éxito, pero que meses después siguen dando lectores. Tipicamente son manuales, tutoriales o cursos y si orientais vuestro blog a este tipo de contenido tendréis un poco más de margen entre posteo y posteo (aunque el trabajo y la calidad que tengáis que poner sea bastante superior)


Clasificación de los medios de comunicación:
Los medios de comunicación de un blog son todos aquellos sistemas que tenemos para comunicarnos con nuestros lectores finales (y por lo tanto conseguir visitas)
- Twiter: el usuario de twiter es nervioso por naturaleza , así que en el momento de publicar nuestro post rapidamente se conectará y lo mirará. Desgraciadamente, en breves minutos se olvidará de ese post :D. Así pues twiter es un método muy eficaz y rápido para generar tráfico, pero un poco pobre para el plazo medio (dia siguiente ).

- Facebook : el usuario de facebook tiene un tiempo de reacción un poco más lento que el twitero, por lo tanto, facilita la creación de tráfico en un plazo medio (horas o incluso dias), pero por desgracia acostumbra a ser un público que no tiene por que gustarle al 100% lo que le estás enviando (es muy normal aceptar cientos de solicitudes de amistad sin mirarselas), así que el público real al que se está llegando es un incógnita.

- Feeds: A estos usuarios se les ha de mimar :). Voluntariamente, sin dudarlo ni un momento han escogido libremente leer tus noticias de cuando publicas cosas nuevas. Les interesa tu tema y hay tanto los "nerviosos" que reaccionan instantáneamente al feed como los que tardan horas o dias para conectarse. Es sin duda el mejor sistema de comunicación entre el blog y sus lectores.

- Links: Si te dedicas ha hacer tutoriales es bastante normal que acabes enviando tus tutos a directorios de tutoriales (han de ser buenos para que te los acepten) . Si tu trabajo es bueno, es bastante normal que te citen en foros o en otros blogs. Si gusta lo que haces tendrás links, así de sencillo. Este tipo de público llega a ti por el boca a boca, buscando información y puede generar una gran cantidad de tráfico al descubrir todos tus post. El problema?? Que no hay forma de controlar esta comunicación más allá que la de hacer posts de calidad.

- Buscadores: Lo que todo el mundo quiere y (casi) nadie consigue. El tráfico que proviene de google o de bing o del que sea, es el más deseado ya que es "carne fresca", gente que no conoce tu blog y que representa cientos de oportunidades de expansión. Me niego a dar consejos aquí para mejorar la posición en los buscadores por que hay cientos de artículos que hablan sobre el tema ( link )

- Recirculación: La recirculación es hacer que los visitantes de tu blog, miren y remiren tus paginas. Formas de conseguirlo?  Linkando bien tus posts relacionados, generando listados de artículos con una temática común y usar herramientas como linkwithin (gadget de Quizás también le interese:) Este tipo de tráfico no es el mejor, ya que no estás llegando a más gente, pero al menos fidelizas a la que tienes para que expandan boca a boca tu blog.


Consejos para aumentar el tráfico paulatinamente:
Estos consejos se basan en mi experiencia personal y a mi me funcionan bastante bien. Cada uno se lo monte como quiera/pueda.

No postees al buen tuntún: Si tienes material y tiempo para un post escribelo, preparalo y guardatelo.

- Márcate un objetivo de visitas diarias: Se realista, pero no vago. Si tus visitas son del tipo : 100,180,170,150,130, podrías plantearte un mínimo de 150 visitas diarias por ejemplo.

Actúa cuando veas que no se va a cumplir el mínimo diario: Con el tiempo podrás saber cuantas visitas a cierta hora del dia necesitas para que cuando acabe el dia tengas el mínimo diario que te has marcado. Actúa significa postea aquel post que tenias guardado en la recámara. Tendrías que postear entre 12 y 8 horas antes de que se acabe el periodo de contabilización de visitas diarias (para que la gente de los diferentes sistemas de comunicación pueda llegar a enterarse).

- Escoge el tipo de post que vas a publicar:  Crees que te faltarán pocas visitas para llegar el mínimo??, postea una vaca lechera, así podrás cumplir el cupo diario y conseguiras aumentar un poco el tráfico diario para el resto de dias. Faltaran muchas visitas para llegar al mínimo? Postea un explosivo, pero recuerda, "pan para hoy, hambre para mañana"

- Intenta que llegue al máximo de gente posible: publicalo en twiter, facebook, google+, o donde quieras/puedas. Si la situación es desesperada y no llegas al mínimo de visitas que te has propuesto te puedes plantear como solución excepcional retwitear posts antiguos que te hayan dado tráfico en su momento. esto, con cuidado, ya que si lo haces con frecuencia tendrá efectos adversos.

-Actualiza tu mínimo de visitas diarias cada cierto tiempo: Cuando ya no te sea un problema conseguir el mínimo de visitas que te habías planteado, proponte un nuevo reto realista y vuelta a empezar.

- Sigue tu intuición e ignora los posts que se titulen "SEO: Como conseguir más tráfico web": :)  Tu blog es tuyo. Tus lectores son únicos. Tus temáticas son las que son. No esperes que nadie te dé 4 normas que te solucionen la vida y aprende sobre la marcha.


En fin, espero que os haya gustado.

Nos vemos

domingo, 28 de octubre de 2012

Simbología electrónica


Hola a todos,

Haciendo el tutorial de electrónica me he dado cuenta que he hecho  un fallo bastante grave... no he explicado los símbolos de cada dispositivo, así que lo haré ahora. Y de paso nos sirve de tabla-recordatorio donde estén todos los símbolos En el nombre de cada elemento pondré un link al tutorial donde se hace referencia.

Los que veáis que están sin link es que todavía no he creado el tutorial correspondiente pero que no falta mucho.

Espero que os guste:


PUERTAS LÓGICAS:
Se Incluyen las diversas nomenclaturas internacionales para que no os extrañe ninguna:

 AND: 

  NAND:    


 OR:


NOR: 
    

NOT:   

 XOR:    
 


RESISTORES:

Resistor:  

Potenciómetro:

Resistor variable:

LDR (Light Dependent Resistance):  

Termistores:  

VDR:

Como saber el valor de una resistencia en función de su código de color:

Por ejemplo, un resistencia rojo-rojo-rojo vale 2200 ohmios.


CONDENSADORES y BOBINAS:

Condensador:

Condensador electrolítico:

Bobinas:

DIODOS:

Diodo:  

LED:  

FotoDiodo:

Diodo Zéner:  

Diodo túnel:

Diodo Varicap:

Diodo sensor de temperatura:

Diodo Schottky:




TRANSISTORES:

Transistor bipolar:  

Transistor FET:

FotoTransistor:


OTROS:

Motor:

Cristal de  Cuarzo :

Fusible:      

Pulsador:

Pila:

Generador de corriente:

Generador de tensión:

Bombilla:

Amperimetro:

Voltímetro:

Amplificador Operacional:

Regulador de tensión:




 Y hasta  aquí he llegado, si creéis que falta algún otro símbolo  o encontráis alguno que no entendéis y queréis que lo incluya, no dudéis en hacérmelo llegar.

Espero que os haya servido,

Nos vemos.


LordPakusBlog
















Entradas populares