8.1 Lenguaje Maquina
Características
Un lenguaje de programación de
bajo nivel es el que proporciona poca o ninguna abstracción del microprocesador
de un ordenador. Consecuentemente es fácilmente trasladado a lenguaje de
máquina.
La palabra “bajo” no implica que
el lenguaje sea inferior a un lenguaje de alto nivel; se refiere a la reducida
abstracción entre el lenguaje y el hardware.
Uso: ventajas e inconvenientes. En
general se utiliza este tipo de lenguaje para programar controladores
(drivers).
La programación en un lenguaje de
bajo nivel como el lenguaje de la máquina o el lenguaje simbólico tiene ciertas
ventajas:
Mayor adaptación al equipo.
Posibilidad de obtener la máxima
velocidad con mínimo uso de memoria.
Pero también tiene importantes
inconvenientes:
Imposibilidad de escribir código
independiente de la máquina.
Mayor dificultad en la
programación y en la comprensión de los programas.
El programador debe conocer más de
un centenar de intrucciones.
Es necesario conocer en detalle la
arquitectura de la máquina.
Características
Se trabaja a nivel de
instrucciones, es decir, su programación es al más fino detalle. Está orientado
a la máquina.
Primera generación
El lenguaje de programación de
primera generación (por sus siglas en inglés, 1GL), es el lenguaje de código
máquina. Es el único lenguaje que un microprocesador entiende de forma nativa.
El lenguaje máquina no puede ser escrito o leído usando un editor de texto, y
por lo tanto es raro que una persona lo use directamente.
Segunda generación
El lenguaje de programación de
segunda generación (por sus siglas en inglés, 2GL), es el lenguaje ensamblador.
Se considera de segunda generación porque, aunque no es lenguaje nativo del
microprocesador, un programador de lenguaje ensamblador debe conocer la
arquitectura del microprocesador (como por ejemplo las particularidades de sus
registros o su conjunto de instrucciones).
8.1.2 Direccionamiento Lenguaje
Maquina
Es la forma en como se accede a la
memoria. Recordar que un programa no puede ejecutarse sino se encuentra en
memoria principal. La forma de acceder a la memoria depende del
microprocesador, pero en general existen dos tipos de direccionamiento: directo
e indirecto.
El direccionamiento directo
también recibe el nombre de direccionamiento absoluto y el acceso a las
direcciones se hace de manera directa. El direccionamiento indirecto también
recibe el nombre de direccionamiento relativo y se basa a partir de una
dirección genérica, generalmente el inicio del programa.
Para acceder a una dirección
relativa se suma a la dirección base el número de espacios de memorias
necesarias. El direccionamiento relativo hace a los programas relocalizables e
independientes. Si la dirección base es el inicio de la memoria fija el
direccionamiento pasa a ser un variante de direccionamiento absoluto.
8.2 Lenguaje Ensamblador
Caracteristicas
El lenguaje Assembly es un tipo de
lenguaje de bajo nivel utilizado para escribir programas informáticos, y constituye
la representación más directa del código máquina específico para cada
arquitectura de computadoras legible por un programador.
Fue usado ampliamente en el pasado
para el desarrollo de software, pero actualmente sólo se utiliza en contadas
ocasiones, especialmente cuando se requiere la manipulación directa del
hardware o se pretenden rendimientos inusuales de los equipos.
Ensambladores [editar]Un
ensamblador crea código objeto traduciendo instrucciones mnemónicas a códigos
operativos, e interpretando los nombres simbólicos para direcciones de memoria
y otras entidades. El uso de referencias simbólicas es una característica
básica de los ensambladores, evitando tediosos cálculos y direccionamiento
manual después de cada modificación del programa. La mayoría de los
ensambladores también incluyen facilidades para crear macros , a fin de generar
series de instrucciones cortas que se ejecutan en tiempo real, en lugar de
utilizar subrutinas[1] .
Los ensambladores son por lo
general más fáciles de programar que los compiladores de lenguajes de alto
nivel, y han estado disponibles desde la década de 1950. Los ensambladores
modernos, especialmente para arquitecturas basadas en RISC, como por ejemplo
MIPS, SPARC y PA-RISC optimizan las instrucciones para explotar al máximo la
eficiencia de segmentación del CPU.
Los ensambladores de alto nivel
ofrecen posibilidades de abstracción que incluyen:
Control avanzado de estructuras.
Procedimientos de alto nivel, declaración de funciones. Tipos de datos que
incluyen estructuras, registros, uniones, clases y conjuntos. Sofisticado
procesamiento de macros.
Lenguaje
[editar]Un programa escrito en lenguaje Assembly consiste en una serie
de instrucciones que corresponden al flujo de órdenes ejecutables que pueden
ser cargadas en la memoria de una computadora. Por ejemplo, un procesador x86
puede ejecutar la siguiente instrucción binaria como se expresa en código
maquina:
Binario: 10110000 01100001
(Hexadecimal: 0xb061) La representación equivalente en Assembly es más fácil de
recordar:
mov al, 061h Esta instrucción
significa:
Mueva el valor hexadecimal 61 (97
decimal) al registro “al”. El mnemónico “mov” es un código de operación u
“opcode” , elegido por los diseñadores de la colección de instrucciones para
abreviar “move” (mover).- El opcode es seguido por una lista de argumentos o
parámetros, completando una instrucción de ensamblador típica.
La transformación del lenguaje
Assembly en código máquina la realiza un programa ensamblador, y la traducción
inversa la puede efectuar un desensamblador. A diferencia de los lenguajes de
alto nivel, aquí hay usualmente una correspondencia 1 a 1 entre las
instrucciones simples del ensamblador y el lenguaje máquina. Sin embargo, en
algunos casos, un ensamblador puede proveer “pseudo instrucciones” que se
expanden en un código de máquina más extenso a fin de proveer la funcionalidad
necesaria. Por ejemplo, para un código máquina condicional como “si X mayor o
igual que” , un ensamblador puede utilizar una pseudoinstrucción al grupo “haga
si menor que” , y “si = 0″ sobre el resultado de la condición anterior. Los
ensambladores más completos también proveen un rico lenguaje de macros que se
utiliza para generar código más complejo y secuencias de datos.
Cada arquitectura de computadoras
tiene su propio lenguaje de máquina, y en consecuencia su propio lenguaje
Assembly. Los ordenadores difieren en el tipo y número de operaciones que
soportan; también pueden tener diferente cantidad de registros, y distinta
representación de los tipos de datos en memoria. Aunque la mayoría de las
computadoras son capaces de cumplir esencialmente las mismas funciones, la
forma en que lo hacen difiere, y los respectivos lenguajes Assembly reflejan
tal diferencia.
Pueden existir múltiples conjuntos
de mnemónicos o sintáxis de Assembly para un mismo conjunto de instrucciones,
instanciados típicamente en diferentes programas ensamblador. En estos casos,
la alternativa más popular es la provista por los fabricantes, y usada en los
manuales del programa.
Código máquina (o lenguaje de máquina) [editar]El lenguaje de máquina está formado
por instrucciones sencillas, que -dependiendo de la estructura del procesador-
pueden especificar:
Registros específicos para
operaciones aritméticas, direccionamiento o control de funciones. Posiciones de
memoria específicas (offset). Modos de direccionamiento usados para interpretar
operandos. Las operaciones más complejas se realizan combinando estas
instrucciones sencillas, que pueden ser ejecutadas secuencialmente o mediante
instrucciones de control de flujo.
Las operaciones disponibles en la
mayoría de los conjuntos de instrucciones incluye:
mover llenar un registro con un
valor constante mover datos de una posición de memoria a un registro o
viceversa escribir y leer datos de dispositivos computar sumar, restar,
multiplicar o dividir los valores de dos registros, colocando el resultado en
uno de ellos o en otro registro realizar operaciones binarias, incluyendo
operaciones lógicas (AND/OR/XOR/NOT) comparar valores entre registros (mayor,
menor, igual) afectar el flujo del programa saltar a otra posición en el
programa y ejecutar instrucciones allí saltar si se cumplen ciertas condiciones
(IF) saltar a otra posición, pero guardar el punto de salida para retornar
(CALL, llamada a subrutinas) Algunas computadoras incluyen instrucciones
complejas dentro de sus capacidades. Una sola instrucción compleja hace lo
mismo que en otras computadoras puede requerir una larga serie de
instrucciones, por ejemplo:
salvar varios registros en la pila
de una sola vez mover grandes bloques de memoria operaciones aritméticas
complejas o de punto flotante (seno, coseno, raíz cuadrada ) El nivel de
lenguaje Assembly tiene aspectos importantes de los niveles de
microarquitectura, en los cuales se encuentra (ISA y sistema operativo) estos
dos se utilizan para la traducción en lugar de la interpretación. Algunas
características del lenguaje se describen a continuación Los programas que
sirven para traducir algún programa para el usuario se llama traductores, el
lenguaje en que esta escrito el programa original se llama lenguaje fuente, el
lenguaje original que sea modificado se llama lenguaje objeto.
Se usa la traducción cuando se
cuenta con un procesador (ya sea hardware o un interprete) para el lenguaje
objeto pero no para el lenguaje fuente, Si la traducción se realiza
correctamente, la ejecución del programa traducido dará exactamente los mismos
resultados que habría dado la ejecución del programa fuente. Hay dos
diferencias entre traducción e interpretación, en la traducción no se ejecuta
directamente el programa original, en el lenguaje fuente se convierte en un
programa equivalente llamado programa objeto o programa binario ejecutable y
este funciona solo cuando se ha acabado la traducción.
El código máquina, un simple
patrón de bits, es hecho legible reemplazando valores crudos por símbolos
denominados mnemónicos. Se inventó para facilitar la tarea de los primeros
programadores que hasta ese momento tenían que escribir directamente en código binario.
antes aún era peor, ya que el código de ceros y unos (el programa) debía
introducirse en una tarjeta perforada. La posición ocupada por cada punto
equivalía a un “1″ o a un “0″ según hubiera un hueco o no. Lo cual suponía una
forma casi idéntica en la que hoy se escriben los datos binaros en soportes
tales como los CDs y DVDs.
Mientras que una computadora
reconoce la instrucción de máquina IA-32
10110000 01100001
para los programadores de
microprocesadores x86 es mucho más fácil reconocer dicha instrucción empleando
lenguaje Assembly:
movb
0×61,%al
(que significa mover el valor
hexadecimal 61 (97 decimal) al registro ‘al’.)
Cada instrucción de la máquina se
transforma en una única instrucción en código simbólico.
Pero además, para mejorar la
legibilidad del programa, el código simbólico introduce instrucciones
adicionales, que no corresponden a ninguna instrucción de la máquina y que
proporcionan información. Se llaman “pseudoinstrucciones”.
El código simbólico puede parecer
de difícil acceso, pero es más fácil de recordar e interpretar que el binario o
el hexadecimal.
Los lenguajes simbólicos no
resuelven definitivamente el problema de cómo programar un ordenador de la
manera más sencilla posible. Para utilizarlos, hay que conocer a fondo el
microprocesador, los registros de trabajo de que dispone, la estructura de la
memoria, y muchas cosas más.
Además, el lenguaje Assembly está
demasiado ligado al microprocesador para que sea posible escribir programas
independientes de la máquina en que van a ejecutarse.
Este código simbólico no puede ser
ejecutado directamente por un ordenador, por lo que es preciso traducirlo
previamente. Pero la traducción es un proceso mecánico y repetitivo, que se
presta a su realización por un programa de ordenador.
Los programas que traducen código
simbólico al lenguaje de máquina se llaman ensambladores (“assembler”, en
inglés), porque son capaces de ensamblar el programa traducido a partir de
varias piezas, procedimientos o subrutinas a código binario (“1″ y “0″) que
entiende el procesador.
Ejemplos de lenguaje Assembly
Ejemplo 1
[editar]El siguiente es un ejemplo del programa clásico Hola mundo escrito
para la arquitectura de procesador x86 (bajo el sistema operativo DOS ).
.model small .stack .data Cadena1
DB ‘Hola Mundo.$’ .code
programa:
mov ax, @data
mov ds, ax
mov dx, offset Cadena1
mov ah, 9
int 21h
end programa
8.2.2 Almacenamiento Lenguaje
Ensamblador
Una de las principales ventajas
del uso del ensamblador, es que se encarga de administrar de manera
transparente para el usuario la creación de memoria, las bifurcaciones y el
paso de parámetros.
Además nos permite acceder
directamente a los recursos de la máquina para un mejor desempeño.
8.3 Registros Lenguaje
Ensamblador
Los registros del procesador se
emplean para controlar instrucciones en ejecución, manejar direccionamiento de
memoria y proporcionar capacidad aritmética. Los registros son espacios físicos
dentro del microprocesador con capacidad de 4 bits hasta 64 bits dependiendo
del microprocesador que se emplee. Los registros son direccionables por medio
de una viñeta, que es una dirección de memoria. Los bits, por conveniencia, se
numeran de derecha a izquierda (15, 14, 13…. 3, 2, 1, 0), los registros están
divididos en seis grupos los cuales tienen un fin específico. Los registros se
dividen en:
• Registros de segmento
• Registros de apuntadores de
instrucciones
• Registros apuntadores
• Registros de propósitos
generales
• Registro índice
• Registro de bandera.
Registros de uso generalà
AX = Registro acumulador, dividido
en AH y AL (8 bits cada uno).- Interviene en las operaciones aritméticas y
lógicas, después de la operación arroja un resultado.
BX = Registro base, dividido en BH
y BL.- Se utiliza en transferencias de datos entre la memoria y el procesador.
CX = Registro contador, dividido
en CH y CL.- Se utiliza como contador en bucles(LOOP), en operaciones con
cadenas(REP), y en desplazamientos(CL).
DX = Registro de datos, dividido
en DH y DL.- Se utiliza en operaciones de multiplicación y división junto con
Ax y en operaciones de entrada y salida de puertos, su mitad inferior DL
contiene el número de puertos.
Registros de segmento.à
Un registro de segmento se utiliza
para alinear en un limite de párrafo o dicho de otra forma codifica la
dirección de inicio de cada segmento y su dirección en un registro de segmento
supone cuatro bits 0 a su derecha.
Un registro de segmento tiene 16
bits de longitud y facilita un área de memoria para direccionamientos conocidos
como el segmento actual. Los registros de segmento son: CS (código), DS
(datos), SS (pila), ES , FS y GS.
Registro Apuntador de
instrucciones.(IP)à
El registro apuntador de
instrucciones (IP) de 16 bits contiene el desplazamiento de dirección de la
siguiente instrucción que se ejecuta.
Registro índice.à
Los registros SI y DI están
disponibles para direccionamientos indexados y para sumas y restas. Que son las
operaciones de punta.
Registro de bandera.è
Los registros de banderas sirven
parar indicar el estado actual de la maquina y el resultado del procesamiento,
Cuando algunas instrucciones piden comparaciones o cálculos aritméticos cambian
el estado de las banderas.
8.3.1 Distribución Lenguaje
Ensamblador
La distribución es el proceso en
el que el programa generado puede ejecutarse en otras máquinas. Con respecto al
ensamblador, la mayoría del direccionamiento se hace relativo para que el
programa sea relocalizable por un programa llamado cargador. En el caso de
programas compiladores se necesitan de las librerías, si son estáticos se
incluyen en el ejecutable por lo que el programa se hace gráfico, si son dinámicas
no pero el programa es más pequeño. Debido a la complejidad del software actual
se necesitan de asistentes para poder instalar y ejecutar un programa.
8.3.2 Asignación Lenguaje
Ensamblador
8.4 Administración Memoria
Lenguaje Ensamblador
La administración de la memoria es
un proceso hoy en día muy importante, de tal
modo que su mal o buen uso tiene
una acción directa sobre el desempeño de memoria.
• En general un ensamblador tiene
un administrador de memoria más limitado que un compilador.
En la mayoría de los lenguajes de
programación el uso de punteros no estaba vigilado por lo que se tienen muchos
problemas con el uso de memoria.
• Los lenguajes más recientes
controlan el uso de punteros y tienen un programa denominado recolector de
basura que se encarga de limpiar la memoria no utilizada mejorando el
desempeño.
No hay comentarios:
Publicar un comentario