Documente Academic
Documente Profesional
Documente Cultură
Introduccin a la Programacin en
Ensamblador
La magia del compilador
Una vez hemos llegado en el estudio de la arquitectura del computador al
punto en que conocemos la ruta de datos, su funcionamiento y sus arquitecturas, es
conveniente justificar la necesidad de que la unidad de control del computador sea
capaz de ejecutar ciertas instrucciones. Haremos esto incluso antes de ver con detalle la
implementacin de la Unidad de Control y la implementacin de las diferentes
arquitecturas, ya que de esta forma justificaremos las instrucciones que creemos.
La programacin en lenguaje ensamblador es ligeramente ms complicada
que la programacin en alto nivel. La complicacin est marcada, fundamentalmente,
por tener que controlar nosotros absolutamente todo lo que el computador tiene que
realizar. Para facilitar la tarea vamos a marcar unas pautas que van encaminadas a
hacernos las cosas ms automticas.
Para la programacin en lenguaje ensamblador vamos a utilizar las tcnicas
aprendidas en algortmica. Como paso previo al desarrollo de un programa en
ensamblador necesitamos tener perfectamente definido lo que pretendemos que haga el
ordenador. Una vez sepamos lo que queremos debemos hacer el programa, pero de
forma directa sino a travs del correspondiente algoritmo; una vez desarrollada la traza
del algoritmo y comprobado que hace lo que pretendemos, el paso siguiente es la
codificacin del algoritmo en lenguaje ensamblador. De esta forma podemos
aprovecharnos de la programacin modular que tanto nos facilita la tarea de la creacin
de programas, en un lenguaje aparentemente hostil a la modularidad.
Para desarrollar el programa lo mejor es tener un esqueleto predefinido e
irlo completando con las partes que son especficas de nuestra aplicacin. Este
esqueleto lo veremos al final cuando ya hayamos estudiado el ncleo de la misma.
Para ayudarnos en el paso del lenguaje algotmico a lenguaje ensamblador
vamos preparar el esqueleto de las estructuras bsicas, de forma que nuestra
programacin sea lo ms homognea y repetitiva que podamos, con la consiguiente
reduccin de errores.
Arquitectura de Ordenadores I
107
Tema 6
condicin
salto_condicional fin_si_001
accin
resto_de_cdigo
Esto nos lleva al primer tipo de instrucciones que vamos a estudiar: los
saltos
Los Saltos
En cdigo mquina la programacin es totalmente secuencial. Una
instruccin se ejecuta detrs de otra indefectiblemente. La nica forma de hacer
programacin estructurada es provocando saltos en la secuencia del programa. Esto
complica notablemente la estructura del programa y su inteligibilidad de cara al
programador (de ah la necesidad de escribir y probar los algoritmos antes de comenzar
a escribir el cdigo mquina).
Los saltos los podemos definir como la ruptura de la secuencia lineal del
programa.
Hay dos tipos de saltos: los incondicionales y los condicionales
Son saltos incondicionales aquellos en los que una vez decodificada la
instruccin el salto se produce siempre. Son tiles para saltar trozos de cdigo de forma
obligatoria y tambin se utilizan para poder hacer algunos trucos que engaen al
microprocesador, en programas muy elaborados. La instruccin de salto suele ser tal
como:
JMP etiqueta
108
Arquitectura de Ordenadores I
Programacin en Ensamblador
JNZ Salta si no cero
JNE Salta si no igual (igual a JNZ)
JS Salta si no signo (si es positivo)
JS Salta si signo (si es negativo)
Ejemplo
si contador>0 entonces
decrementar contador
fin si
En ensamblador
si_001:
registro
CMP AX, 0
JG entonces_001
; evaluamos la condicin
; si condicin verdadera ejecuto la
JMP fin_si_001
DEC contador
; accin(es)
; resto del cdigo
accin
accin
entonces_001:
fin_si_001:
CMP AX, 0
JLE fin_si_001
DEC contador
; evaluamos la condicin
; salto si complementario de condicin
; accin(es)
fin_si_001:
Arquitectura de Ordenadores I
109
Tema 6
accin2
fin si
condicin
salto_condicional entonces_001
accin2
JMP fin_si_001
accin1
resto_de_cdigo
En ensamblador
si_001:
registro
accin1
sino_001:
entonces_001:
fin_si_001:
CMP AX, 0
JG entonces_001
; evaluamos la condicin
; si condicin verdadera ejecuto la
MOV AX, #1
MOV salir, AX
JMP fin_si_001
DEC contador
;
;
;
;
;
condicin
salto_condicional fin_mientras_001
accin
JMP mientras_001
fin_mientras_001: resto_de_cdigo
Ejemplo
mientras salir<>0 hacer
contador := contador + 1
fin mientras
En ensamblador quedara:
mientras_001:
110
Programacin en Ensamblador
CMP AX, 0
JZ fin_mientras_001
INC contador
JMP mientras_001
;
;
;
;
;
evaluamos la condicin
si la condicin es falsa termino
accin(es)
la condicin no es cierta, omito
la accin
fin_mientras_001: resto_de_cdigo
Donde hemos visto una nueva instruccin aritmtica, INC, cuya misin es
incrementar el operando que viene a continuacin.
accin
condicin
salto_condicional repetir_001
Ejemplo
repetir
distancia := distancia + 3
hasta que distancia > 100
En ensamblador quedara :
repetir_001:
;
;
;
;
;
;
Arquitectura de Ordenadores I
111
Tema 6
Esta estructura se caracteriza por tener los lmites bien definidos, lo cual se
corresponde en ensamblador con un bucle tpico.
desde_001:
hasta_001:
fin_desde_001:
;
;
;
;
;
;
;
hasta_001:
fin_desde_001:
MOV variable, CX
CMP CX, final
JLE hasta_001
resto_de_cdigo
;
;
;
;
;
;
;
;
;
Ntese que siguen habiendo dos saltos, pero el primero slo se evala la
primera vez y a continuacin, dentro del bucle propiamente dicho, solo se evala el
segundo una vez por iteracin.
Ejemplo
para i := 1 hasta N hacer
a := i
fin para
En ensamblador quedara :
desde_001:
hasta_001:
fin_desde_001:
MOV CX, #1
CMP CX, N
JG fin_desde_001
MOV a, CX
INC CX
MOV i, CX
CMP CX, N
JLE hasta_001
resto_de_cdigo
;
;
;
;
;
;
;
;
Solo es necesario si vamos a utilizar la variable dentro del bucle. Si la vamos a utilizar al salir del bucle solo sera
necesario actualizarla una vez fuera del bucle. Si no se utiliza nunca sobra su declaracin y cualquier asignacin.
112
Arquitectura de Ordenadores I
Programacin en Ensamblador
hasta_001:
fin_desde_001:
;
;
;
;
;
;
n: accinN
sino
accinD
fin segn
segun_ma_001:
segun_me_001:
sgn_acN_001:
accinN
Arquitectura de Ordenadores I
;
;
;
;
;
;
ejecuta la accin 1
ejecutamos la siguiente sentencia
ejecuta la accin 2
ejecutamos la siguiente sentencia
ejecuta la accin 1
ejecutamos la siguiente sentencia
; ejecuta la accin N
113
Tema 6
sgn_acD_001:
fin_segun_001:
JMP fin_segn_001
accinD
resto_del_cdigo
dw sgn_acN_001
sino_001:
dw sgn_acD_001
; diccionario del segn 001
dicc_sgn_001:
dB +-*/= ^
f_dicc_sgn_001:
; comienzo de la implementacin del segn 001
; bsqueda en el diccionario
segn_001:
MOV BX, offset dicc_sgn_001
; BX apunta al diccionario
DEC BX
; para el preincremento
MOV CX, f_dicc_sgn_001-dicc_sgn_001
; cargo en CX el nmero de smbolos
MOV AL, valor
; pongo en AL el valor del segn
bucle_001:
INC BX
; preincremento de BX (++BX)
CMP AL, [BX]
; compruebo si valor est en la tabla
LOOPNE bucle_001
; cierra el bucle si no son iguales y
; CX es mayor que cero
SUB BX, dicc_sgn_001 ; dejo en BX la posicin relativa
; del smbolo
SHL BX, 1
; multiplico BX por 2, la direccin
; tiene la longitud de una palabra
CMP CX, 0
; compruebo la forma de salir
JNZ salto_sgn_001
; salta si el smbolo est en la tabla
MOV BX, sino_sgn_001-tsalto_sgn_001
; dejo en BX el desplazamiento
; del caso por defecto
salto_sgn_001:
MOV IP, Tsalto_sgn_001[BX]
; salto encubierto
; aqu no llega nunca
; el resto del cdigo es igual que en el ejemplo del caso anterior
; implementacin de las acciones
sgn_ac1_001:
accin1
; ejecuta la accin 1
JMP fin_segn_001
; ejecutamos la siguiente sentencia
sgn_ac2_001:
accin2
; ejecuta la accin 2
JMP fin_segn_001
; ejecutamos la siguiente sentencia
sgn_ac1_001:
accin3
; ejecuta la accin 3
JMP fin_segn_001
; ejecutamos la siguiente sentencia
114
Arquitectura de Ordenadores I
Programacin en Ensamblador
sgn_acN_001:
sgn_acD_001:
fin_segun_001:
accinN
JMP fin_segn_001
accinD
resto_del_cdigo
; ejecuta la accin N
; ejecutamos la siguiente sentencia
; ejecuta la accin por defecto
Problema:
Se recomienda al alumno la implementacin del segn por el mtodo de
las comparaciones sucesivas.
Subprogramas
Por ltimo nos queda ver, para terminar esta introduccin, las llamadas a
subprogramas. Las llamadas vienen a ser algo as como:
Subprograma modulo_1 (parmetros)
variables
inicio
accin1
accin2
accinN
fin subprograma
accinN
RET
; Llamada al mdulo 1
CALL modulo_1
resto_de_cdigo
Arquitectura de Ordenadores I
115
Tema 6
CALL modulo_1
CALL modulo_1
Accin_1
Accin_2
Accin_N
RET
Nos falta hablar del paso de parmetros. Para pasar los parmetros
podemos utilizar los registros del procesador. Esto tiene el inconveniente de que los
parmetros son siempre por referencia, el resultado que tome el registro aparece en el
programa principal tambin, con el consiguiente inconveniente. Si los pasamos mediante
variables, no podemos llamar a un procedimiento desde dentro de l mismo, puesto que
destruiramos las variables de la primera llamada. Por otro lado tenemos que recordar
de alguna forma el punto donde hay que retornar cuando se termine de ejecutar el
procedimiento.
Llegamos de esta forma a la PILA. La pila es una zona de memoria donde
trabajaremos de una forma especial y que nos permite resolver los problemas
planteados anteriormente. El juego de instrucciones requiere dos nuevos elementos:
meter un dato en la pila (PUSH) y retirar un dato de la pila (POP). Cuando estudiemos
los distintos modos de direccionamiento hablaremos con ms en detalle de estas
instrucciones.
116
Arquitectura de Ordenadores I