Ensamblador
Ensamblador
Ensamblador
Amelia Ferreira
Vicente Robles
Caracas, 2007
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
Introduccin................................................................................................................... 6
Captulo 1. La plataforma IA-32 .................................................................................... 8
Descripcin general de la mquina .............................................................................................. 8
Tipos de datos...............................................................................................................................................8
Registros .....................................................................................................................................................10
Registros de propsito general .............................................................................................................10
Registros de segmento ..........................................................................................................................12
Registro apuntador de instruccin........................................................................................................17
Registros de punto flotante ...................................................................................................................17
Banderas......................................................................................................................................................17
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
3
Instrucciones aritmticas y lgicas ............................................................................................ 62
add (suma) .............................................................................................................................................62
sub (resta)...............................................................................................................................................63
inc (incremento) ....................................................................................................................................63
dec (decremento) ...................................................................................................................................63
neg (negacin aritmtica) .....................................................................................................................64
not (negacin lgica).............................................................................................................................64
and (y lgico).........................................................................................................................................64
or (o lgico) ...........................................................................................................................................65
xor (or exclusivo) ..................................................................................................................................66
shl (desplazamiento lgico a la izquierda)...........................................................................................66
shr (desplazamiento lgico a la derecha) .............................................................................................67
sar (desplazamiento aritmtico a la derecha).......................................................................................67
mul (multiplicacin de enteros sin signo)............................................................................................68
imul (multiplicacin de enteros con signo) .........................................................................................68
imul con un operando.......................................................................................................................68
imul con dos operandos ...................................................................................................................68
imul con tres operandos ...................................................................................................................69
cwd (convierte palabra en palabra doble) ............................................................................................69
cltd (convierte palabra doble a palabra cudruple) .............................................................................69
div (divisin de enteros sin signo) .......................................................................................................69
idiv (divisin de enteros con signo) .....................................................................................................70
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
4
Ejercicios...................................................................................................................................... 116
Ejercicios...................................................................................................................................... 124
Ejercicios...................................................................................................................................... 130
Ejercicios...................................................................................................................................... 143
Ejercicios...................................................................................................................................... 153
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
5
fdiv (divisin) ......................................................................................................................................161
Instrucciones de comparacin .................................................................................................................163
Ejercicios...................................................................................................................................... 165
Ejercicios...................................................................................................................................... 196
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
Introduccin
Este libro est destinado a aquellas personas que deseen aprender a programar
en lenguaje ensamblador para la plataforma IA-32 bajo ambiente Linux.
Los ejemplos se refieren al compilador gcc (GNU compiler collection). El
ensamblador de gcc se llama as y por formar parte de gcc comnmente se
conoce como gas. Este libro no pretende cubrir todas y cada una de las
instrucciones del lenguaje ensamblador sino las ms comunes y presenta una
serie de ejemplos y ejercicios para ayudar al lector en la programacin. Con el
conjunto de herramientas presentadas es posible desarrollar programas
complejos que solucionen una gran variedad de problemas.
La programacin en lenguaje ensamblador ofrece diferentes ventajas. Un
programa escrito en lenguaje ensamblador requiere considerablemente menos
memoria y tiempo de ejecucin que un programa escrito en un lenguaje de alto
nivel. La programacin en lenguaje ensamblador depende de la arquitectura del
computador sobre el cual se trabaja, sto es importante para entender el
funcionamiento interno de la mquina, por ello al programar en ensamblador se
llega a comprender cmo funciona el computador y cmo es su estructura
bsica. La capacidad de poder escribir programas en lenguaje ensamblador es
muy importante para los profesionales del rea de Sistemas Operativos debido a
que los programas residentes y rutinas de servicio de interrupcin casi siempre
son desarrollados en lenguaje ensamblador.
Adems, an cuando la mayora de los especialistas en programacin desarrolla
aplicaciones en lenguajes de alto nivel, que son ms fciles de escribir y de
mantener, una prctica comn es codificar en lenguaje ensamblador aquellas
rutinas que han causado cuellos de botella en el procesamiento.
La organizacin del libro corresponde al proceso de aprendizaje de la
programacin en lenguaje ensamblador, primero se describen las caractersticas
bsicas de la arquitectura de la mquina sobre la cual se va a trabajar, luego el
entorno de programacin es decir, los programas y herramientas necesarios
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
7
para realizar la programacin. Este captulo sirve de introduccin al uso de estas
herramientas y luego de consulta a medida que van aprendiendo nuevos
conceptos ya que provee la informacin necesaria para la deteccin y correccin
de errores del programa escrito en lenguaje ensamblador. Los siguientes
captulos describen la estructura del programa, cmo declarar datos y cmo
utilizar las instrucciones bsicas. Luego se explica cmo realizar operaciones de
lectura y escritura de informacin para posteriormente pasar a la explicacin de
la programacin de estrcuturas condicionales, ciclos y el uso de arreglos. Ms
adelante se describen las convenciones para el desarrollo de procedimientos.
Hasta este punto se cubren los conceptos bsicos de la programacin en
lenguaje ensamblador, los captulos siguientes proveen una visin un poco ms
detallada de ciertos aspectos como son el manejo de cadenas de caracteres lo
cual es posible realizar de manera ms eficiente con un conjunto de
instrucciones dedicadas. Estas instrucciones se presentan en el captulo 10.
Luego se describe cmo programar utilizando operaciones de punto flotante y
finalmente el ltimo captulo est dedicado al manejo de archivos.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
Tipos de datos
Los datos se pueden accesar de diversas maneras. Se puede leer un slo byte (8
bits) o un conjunto de bytes. En esta mquina en particular se denomina palabra
a dos bytes y doble palabra a cuatro bytes. Los datos pueden representarse en
notacin binaria, octal, decimal o hexadecimal:
Binaria
0b1000
0b1100
0b1101011011
Octal
08
014
01533
Decimal
8
12
859
Hexadecimal
0x8
0xC
Ox35B
De esta forma, todo dato precedido por el prefijo 0b ser interpretado por la
mquina como un nmero binario. De forma similar, los prefijos 0 y 0x
denotarn datos octales o hexadecimales respectivamente. Por ltimo, todo
dato que no contenga uno de estos prefijos ser interpretado por defecto como
decimal.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
9
Esta sintaxis es vlida tanto para el ensamblador gas como para el compilador
gcc, a excepcin del prefijo 0b el cual no est soportado por este ltimo al
momento de escribir estas lneas (se tiene previsto incluir soporte para el mismo
en el futuro).
Los tamaos de los diferentes tipos de datos del lenguaje de programacin C
son los siguientes:
Declaracin en C
char
short
int
unsigned
long int
unsigned long
char *
float
double
long double
Sufijo de gas
b
w
l
l
l
l
l
s
l
t
En gas las instrucciones utilizan un sufijo para indicar el tamao de los datos
sobre los cuales operan. El mismo puede ser omitido en aquellas instrucciones
en las cuales el tamao de al menos uno de los operandos pueda ser deducido
por gas de manera implcita. Sin embargo, debe ser incluido obligatoriamente
en casos en que los operandos no tengan un tamao implcito (por ejemplo una
operacin entre inmediato y memoria).
Los sufijos disponibles en gas son: b (byte), para denotar operandos de un
byte, w (word) para denotar operandos de dos bytes o una palabra, y l (long)
para denotar operandos de cuatro bytes o una palabra doble.
Por ltimo, es importante tener presente que el sistema guarda los datos en
memoria en secuencia inversa de bytes (little endian) lo cual trae como
consecuencia que el byte menos significativo se ubique en la posicin de menor
orden y el byte ms significativo en la posicin de memoria de mayor orden.
Por ejemplo si se transfiere el dato 0x457A a las posiciones consecutivas de
memoria 0x100 y 0x101 se ubica el byte 0x7A en la posicin 0x100 y el byte
0x45 en la posicin 0x101.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
10
Registros
Tipo de registro
De propsito general
De segmento
Apuntador de instruccin
De punto flotante
Nmero y tamao
8 registros de 32 bits
6 registros de 16 bits
1 registro de 32 bits
8 registros de 80 bits
Descripcin
Almacenan datos. Para uso del programador
Permiten direccionar la memoria
Apunta a la siguiente instruccin a ejecutar
Se usan para aritmtica punto flotante
registros
de
propsito
general
se
utilizan
para
almacenar
datos
Descripcin
Acumulador para operaciones aritmetico lgicas
Registro base para acceder a memoria
Contador para algunas instrucciones
Registro de datos usado para algunas operaciones de entrada/salida
Apuntador a destino para operaciones con cadenas de caracteres
Apuntador a origen para operaciones con cadenas de caracteres
Apuntador de pila
Apuntador de marco de pila
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
11
Los tamaos de los registros %eax, %ebx, %ecx y %edx son los siguientes:
%al (8 bits)
%bl (8 bits)
%cl (8 bits)
%dl (8 bits)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
12
Los tamaos de los registros %edi, %esi, %esp y %ebp son los siguientes:
%di (16 bits)
Registros de segmento
Los registros de segmento se utilizan para referenciar reas de memoria. La
plataforma IA-32 permite direccionar la memoria segn el modelo de memoria
lineal o el modelo de memoria segmentada.
El modelo de memoria lineal presenta todo el espacio de direcciones de la
memoria como un espacio contiguo. Todas las instrucciones, los datos y la pila
se encuentran en el mismo espacio de direcciones de memoria. Cada posicin
de memoria se referencia mediante una direccin especfica llamada "direccin
lineal".
El problema del enfoque anterior consiste en que todos los datos se encuentran
mezclados entre si y a la vez distribuidos a lo largo de todo el espacio de
direcciones memoria, lo cual hace que su manejo sea engorroso e ineficiente. El
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
13
modelo de memoria segmentada resuelve este problema dividendo el espacio
de direcciones en segmentos independientes entre si. Cada segmento contiene
un tipo especfico de informacin, es decir el cdigo (las instrucciones) se ubica
en un segmento, los datos en otro y la pila en un tercer segmento. Las
posiciones de memoria en los segmentos se definen por direcciones lgicas.
Una direccin lgica est compuesta por una direccin de segmento y un
desplazamiento. El procesador traduce una direccin lgica a una direccin
lineal.
Los procesadores de la familia Intel poseen un grupo de registros creados con el
fin de soportar el modelo de memoria segmentada, los cuales son conocidos
como registros de segmento:
Registro de segmento
cs
ds
ss
es
fs
gs
Descripcin
Segmento de cdigo
Segmento de datos
Segmento de pila
Apuntador de segmento extra
Apuntador de segmento extra
Apuntador de segmento extra
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
14
Por ejemplo:
Segmento: DS
Desplazamiento: 0x8A00
0x28A00
DATO
Desplazamiento
0x2000
0x20000
DS
0x00000
Sin embargo, con el paso de los aos este enfoque result ser insuficiente, ya
que por ejemplo, no haba forma de determinar si un desplazamiento causaba
que la direccin lineal cayera fuera del segmento. Para solventar ste y otros
problemas de seguridad, se implement a partir del procesador 80286 el modo
protegido.
En el modo protegido, el registro de segmento ya no contiene la direccin base
del segmento, sino un selector de segmento, el cual permite seleccionar un
Permisos de acceso
byte 0
Permisos de acceso
AV
Lmite (19-16)
byte 0
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
15
almacenarse en el registro de segmento en modo real. Adicionalmente se cuenta
con un campo de lmite de segmento que puede ocupar 16 20 bits, lo que
determina el tamao mximo de los segmentos en 64KB o 1MB. El descriptor de
segmento del 80386 incluye una bandera (G) que indica que el campo lmite
debe ser multiplicado por 4K, permitiendo entonces la existencia de segmentos
entre 4KB y 4 GB.
El descriptor de 80386 incluye dos banderas adicionales. La primera de ellas
(D/B), permite determinar si se est trabajando en modo de 16 32 bits. La
segunda (AVL) puede ser utilizada por los sistemas operativos para marcar el
segmento descrito como disponible o no (Available). El campo de permisos de
acceso posee los siguientes subcampos:
7
P
5
DPL
TIPO
Selector
TI
RPL
El campo RPL ( Request Privilege Level) permite indicar el nivel de privilegio con
el cual se est accediendo al segmento, siendo 00 el nivel ms bajo y 11 el ms
alto. Este valor debe ser mayor o igual al del campo DPL del descriptor
correspondiente. Adicionalmente el campo TI (Table Indicador) es una bandera
que permite escoger la tabla en la cual ser seleccionado el descriptor de
segmento con los bits restantes (0 = tabla de descriptores globales, 1 = tabla
de descriptores locales). Los descriptores globales son utilizados por todos los
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
16
programas y a menudo se les conoce como descriptores de sistema, mientras
que los descriptores locales son exclusivos de un programa particular y a
menudo se les conoce como descriptores de aplicacin.
De esta forma, el mismo acceso a memoria que ejemplificamos anteriormente,
se llevara a cabo de la siguiente manera en modo protegido:
Segmento: DS
Desplazamiento: 0x8A00
Tabla de
descriptores
locales
Lmite del
segmento
0x2A000
DATO
0x28A00
Desplazamiento
0x0015
DS
00
93
00
A0
00
02
00
00
0x20000
Descriptor 1
Descriptor 0
0x00000
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
17
mente tambin que la memoria puede estar paginada, en cuyo caso ser
necesario transformar las direcciones lineales (virtuales) a direcciones fsicas o
reales. Por ltimo, cabe acotar que los registros ES, FS y GS apuntan a
segmentos de datos (o seleccionan descriptores de segmentos de datos).
Registro apuntador de instruccin
El registro apuntador de instruccin (eip) o contador de programa contiene la
direccin de la prxima instruccin a ejecutarse.
Banderas
Las banderas proveen una manera de obtener informacin acerca de del estado
actual de la mquina y el resultado de procesamiento de una instruccin. La
plataforma IA-32 utiliza un registro de 32 bits llamado EFLAGS que contiene las
banderas. Las banderas ms comunmente usadas son las siguientes:
Bandera
CF
PF
AF
ZF
SF
DF
OF
Bit
0
2
4
6
7
10
11
Nombre
Bandera de acarreo (carry flag)
Bandera de paridad (parity flag)
Bandera de acarreo auxiliar (adjust flag)
Bandera de cero (zero flag)
Bandera de signo (sign flag)
Bandera de direccin (direction flag)
Bandera de desbordamiento (overflow flag)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
18
La bandera de cero se activa si el resultado de una operacin aritmtico lgica
es cero.
La bandera de signo muestra el bit ms significativo del resultado de una
operacin, el cual denota el signo del nmero.
La bandera de direccin controla la seleccin de autoincremento (D=0) o
autodecremento (D=1) de los registros %edi o %esi durante las operaciones con
cadenas de caracteres. La bandera de direccin slo se utiliza con las
instrucciones para el manejo de cadenas de caracteres.
La bandera de desbordamiento se utiliza en la aritmtica de enteros con signo
cuando un nmero sobrepasa la capacidad de representacin del registro.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
19
las
etapas
correspondientes
al conjunto
de herramientas
de
Pre-procesador
(cpp)
Compilador
(ccl)
Ensamblador
(as)
Enlazador
(ld)
Programa
objeto
ejemplo
ejemplo.c:
#include <stdio.h>
int main()
{
printf(programa de ejemplo\n);
return 0;
}
Con gcc, la traduccin de este programa fuente a un archivo objeto ejecutable
se realiza de la siguiente manera:
linux>
ejemplo.c
#include <stdio.h>
archivo de encabezado
stdio.h
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
20
Pre-procesador
(cpp)
ejemplo.c
Luego,
ejemplo.i.
ejemplo.i
ejemplo.s.
Compilador
(ccl)
ejemplo.i
ejemplo.s
ejemplo.s y lo traduce en
ejemplo.o.
ejemplo.s
Ensamblador
(as)
ejemplo.o
Luego el enlazador (ld) enlaza ese archivo objeto con otros archivos asociados a
l, en este caso ya que el programa llama una biblioteca (la funcin printf forma
parte de la biblioteca estndar de entrada/salida) el enlazador se encarga de
enlazar el programa con esta biblioteca en particular. Su salida es un archivo
objeto ejecutable llamado
ejemplo.
Biblioteca
estndar
ejemplo.o
Enlazador
(ld)
ejemplo
./ejemplo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
21
programa de ejemplo
linux>
El compilador gcc se puede ejecutar con varias opciones. Cabe destacar que
Linux diferencia entre maysculas y minsculas por lo cual un comando (u
opcin) en mayscula ser diferente a un comando (u opcin) con el mismo
nombre en minscula. Entre las opciones ms importantes tenemos:
-o
-S
-c
-O
-g
.s.
Usando el programa
linux>
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
22
Produce como salida el programa en lenguaje ensamblador:
.file
"ejemplo.c"
.section
.rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "programa de ejemplo"
.text
.p2align 2,,3
.globl main
.type
main,@function
main:
pushl
%ebp
movl
%esp, %ebp
subl
$8, %esp
andl
$-16, %esp
subl
$12, %esp
pushl
$.LC0
call
puts
xorl
%eax, %eax
leave
ret
.Lfe1:
.size
main,.Lfe1-main
.ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
Existe otra opcin de (-v, verbose), la cual nos permite observar la manera en la
que gcc invoca a cada una de las herramientas mencionadas (el compilador, el
ensamblador y el enlazador) para generar el archivo ejecutable. Por ejemplo, si
repetimos la compilacin del archivo ejemplo.s utilizando esta opcin, podemos
distinguir cada uno de los pasos descritos anteriormente:
linux>
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
23
En este caso, se pueden observar las siguientes lneas dentro de la salida
producida por gcc:
...
/usr/libexec/gcc/i386-redhat-linux/4.0.2/cc1 -quiet -v ej em pl o. c quiet -dumpbase ejemplo.c -auxbase ejemplo -version -o
/tm p/ cc VK 44 SE .s
...
as -V -Qy - o /t mp /c c4 zi Th v. o / tmp /c cV K44 SE .s
...
/usr/libexec/gcc/i386-redhat-linux/4.0.2/col le ct 2 --eh-frame-hdr -m
elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o e je mp lo
/usr/lib/gcc/i386-redhat-linux/4.0.2/../../../crt1.o /usr/lib/gcc/i386redhat-linux/4.0.2/../../../crti.o /usr/lib/gcc/i386-redhatlinux/4.0.2/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/4.0.2 L/usr/lib/gcc/i386-redhat-linux/4.0.2 -L/usr/lib/gcc/i386-redhatlinux/4.0.2/../../.. /tmp /c c4 zi Th v. o -lgcc --as-needed -lgcc_s --noas-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/usr/lib/gcc/i386-redhat-linux/4.0.2/crtend.o /usr/lib/gcc/i386-redhatlinux/4.0.2/../../../crtn.o
...
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
24
Cada una de las herramientas llamadas por gcc cuenta con su propio conjunto
de opciones que permiten un mayor control sobre todo el proceso de traduccin
en caso de ser necesario.
Finalmente, es posible realizar todos los pasos del proceso de traduccin de
manera manual, llamando a cada una de las herramientas con las opciones ms
adecuadas de acuerdo a lo que se quiere lograr. Por ejemplo, para generar el
archivo ejecutable ejemplo podemos realizar los siguientes pasos:
Binutils
Como mencionamos anteriormente, si utilizamos la opcin c se produce un
archivo en cdigo de mquina (binario). De igual forma podemos obtener este
archivo invocando manualmente a las herramientas correspondientes. Sin
embargo, existen casos en que necesitamos llevar a cabo el proceso inverso, es
decir, obtener la representacin en lenguaje ensamblador de un programa en
lenguaje de mquina.
En la vida real se dan situaciones en que se nos proporciona una biblioteca
previamente compilada (.o, .a, .so) sin ningn tipo de documentacin, y
debemos averiguar la forma correcta de utilizarla. (Por ejemplo, imagine que se
le proporciona la biblioteca para interactuar con un dispositivo de hardware,
pero no se le entrega el cdigo fuente ni una documentacin que permita
conocer las funciones disponibles para ello).
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
25
En este caso ser necesario identificarlas de alguna manera, bien sea
obteniendo una lista de los smbolos globales que identifican a dichas funciones
(entry points) o bien sea desensamblando el cdigo binario y analizando el
mismo.
Es posible llevar a cabo estas tareas utilizando un grupo de herramientas
provistas por GNU para el manejo de archivos binarios, conocidas como binutils,
entre las cuales se encuentran:
ld
El enlazador GNU
as
El ensamblador GNU
addr2line
ar
nm
objcopy
objdump
readelf
size
strings
strip
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
26
Lo cual produce la salida:
00000000
0: 55
1: 89
3: 83
6: 83
9: 83
c: 68
11: e8
16: 31
18: c9
19: c3
<main>:
e5
ec
e4
ec
00
fc
c0
08
f0
0c
00 00 00
ff ff ff
push
mov
sub
and
sub
push
call
xor
leave
ret
%ebp
%esp,%ebp
$0x8,%esp
$0xfffffff0,%esp
$0xc,%esp
$0x0
12 <main+0x12>
%eax,%eax
-D
-G
-l
-r
-R
-t
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
27
linux>
linux>
addr2line -e ejemplo.o -s
0
ejemplo.c:4
main()
{
11
printf(programa de ejemplo\n);
ejemplo.c:5
19
pushl %ebp
call <main+0x12>
ejemplo.c:7
ret
addr2line pueden arrojar como salida la misma lnea de cdigo fuente original.
En captulos posteriores se dar una explicacin ms detallada de este tema.
Algunas opciones importantes de esta herramienta son:
-e
-s
evita que se imprima la ruta completa del archivo en lenguaje de alto nivel
al consultar una direccin.
-f
readelf ejemplo.o -s
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
28
La tabla de smbolos '.symtab' contiene 10 entradas:
Num
0
1
2
3
4
5
6
7
8
9
linux>
Valor
Tam
Tipo
Union
Vis
00000000
0
NOTYPE LOCAL DEFAULT
00000000
0
FILE
LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000
0
SECTION LOCAL DEFAULT
00000000 26
FUNC
GLOBAL DEFAULT
00000000
0
NOTYPE GLOBAL DEFAULT
Ind
UND
ABS
1
3
4
5
7
6
1
UND
Nombre
ejemplo.c
main
puts
readelf ejemplo.o r
Info
00000501
00000902
Tipo
R_386_32
R_386_PC32
Val. Simbolo
00000000
00000000
Nom. Simbolo
.rodata.str1.1
puts
readelf ejemplo.o S
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
29
Hay 11 encabezados de seccin, comenzando en el desplazamiento: 0xec:
Encabezados de Seccin:
[Nr]
Nombre
Tipo
Direc
Desp
Tam
ES
[ 0]
.text
NULL
00000000
000000
000000
00
[ 1]
.text
PROGBITS
00000000
000034
00001a
00
[ 2]
.rel.text
REL
00000000
00035c
000010
08
[ 3]
.data
PROGBITS
00000000
000050
000000
00
[ 4]
.bss
NOBITS
00000000
000050
000000
[ 5]
.rodata.str1.1
PROGBITS
00000000
000050
[ 6]
.comment
PROGBITS
00000000
[ 7]
.note.GNU-stack
PROGBITS
[ 8]
.shstrtab
[ 9]
[10]
Opt
En
Inf
Al
WA
00
WA
000014
01
AMS
000064
00002d
00
00000000
000091
000000
00
STRTAB
00000000
000091
000058
00
.symtab
SYMTAB
00000000
0002a4
0002a4
10
10
.strtab
SYMTAB
00000000
000344
000015
00
AX
linux>
readelf ejemplo.o x 5
ASCII
programa
0x00000000 6D 65 6A 65 20 65 64 20 67 6F 72 70 67 6F 72 70 ejem
0x00000010
6F 6C 70 plo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
de
30
Las principales opciones de readelf son las siguientes:
-a
-h
-S
-s
-r
-x
El depurador gdb
Un
programas,
permitiendo al usuario ejercer cierto control sobre los mismos a medida que los
estos se ejecutan, y examinar el estado del sistema (variables, registros,
banderas, etc.) en el momento en que se presente algn problema. El propsito
final de un depurador consiste en permitir al usuario observar y comprender lo
que ocurre dentro de un programa mientras el mismo es ejecutado.
En los sistemas operativos UNIX/LINUX, el depurador ms comnmente utilizado
es gdb, es decir el depurador de GNU. ste ofrece una cantidad muy extensa y
especializada de opciones. Es muy importante entender el hecho de que un
depurador trabaja sobre archivos ejecutables. Esto quiere decir que el mismo
funciona de forma independiente al lenguaje en que se escribi el programa
original, sea ste lenguaje ensamblador o un lenguaje de medio o alto nivel
como C.
Ejecucin de programas con el depurador
Para iniciar el depurador, se utiliza el comando gdb. Esto ocasionar que
aparezca un nuevo prompt simbolizado por la cadena (gdb), lo que indica que
el depurador est listo para recibir una orden (de forma similar al smbolo $ o #
en una cnsola de Linux):
linux> gdb
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
(gdb)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
31
Una vez dentro del depurador, existen diferentes comandos para analizar el
comportamiento de un programa. Un hecho a resaltar es la gran semejanza que
existe entre la cnsola proporcionada por GDB y la consola que comnmente
utilizamos para llevar a cabo todas las tareas en Linux. En particular, es
importante mencionar que la utilizacin del tabulador para completar los
comandos automticamente tambin funciona dentro de gdb. Tambin es
posible utilizar las teclas Flecha Arriba y Flecha Abajo para navegar por los
ltimos comandos que se han utilizado.
El comando help permite obtener ayuda sobre cada uno de los comandos. Esta
ayuda funciona de una forma jerrquica. Por ejemplo, si se utiliza el comando
help sin argumentos, se desplegar una lista con las principales categoras
sobre las cuales es posible obtener ayuda:
(gdb) help
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
32
Dentro del depurador, el primer paso es cargar el programa ejecutable que se
quiere depurar. Para ello se utiliza el comando file. Por ejemplo, supongamos
que se desea depurar el programa de ejemplo que utilizamos en secciones
anteriores:
(gdb) file ejemplo
Reading symbols from /root/ejemplo...(no debugging symbols found)...done.
Using host libthread_db library "/lib/libthread_db.so.1".
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
33
RES0:
RESP:
RESN:
A:
N:
.section .data
.asciz "El resultado de la suma es cero (%d)\n"
.asciz "El resultado de la suma es positivo (%d)\n"
.asciz "El resultado de la suma es negativo (%d)\n"
.long 1,10,-8,7,14,-3,23,-52
.long 8
.section .text
.globl _start
_start:
# suma = 0
#i=0
ciclo:
cmpl N, %ecx
jge fciclo
movl A(,%ecx,4), %edx
addl %edx, %eax
addl $1, %ecx
jmp ciclo
pushl %eax
cmpl $0, %eax
je R0
jl RN
# Mientras i<N
pushl $RESP
jmp fin
pushl $RESN
jmp fin
pushl $RES0
jmp fin
call printf
addl $8, %esp
movl $1, %eax
xorl %ebx, %ebx
int $0x80
# Muestra el resultado
fciclo:
RP:
RN:
R0:
fin:
# Carga A[i]
# suma += A[i]
# i++
# Repite el ciclo
# Primer argumento del printf
# Seleccionar el mensaje
# Termina el programa
Si se analiza el programa, es muy fcil descubrir los errores que llevaron a este
resultado, ya que los mismos son evidentes. Sin embargo, recomendamos no
examinar el cdigo fuente, sino proseguir con la lectura. En las siguientes
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
34
pginas se utilizar el depurador para determinar lo que est ocurriendo, tal y
como se hara en un caso real en el que no se tenga acceso al cdigo fuente, o
los errores no sean tan evidentes como para detectarse por simple inspeccin.
Comandos bsicos de control
Todo depurador permite al usuario controlar la ejecucin del programa
analizado, indicando bsicamente cuando detener dicha ejecucin, o que
fragmentos del programa ejecutar. A continuacin se muestra una breve
descripcin de los comandos ms comnmente utilizados en el depurador gdb
para controlar la ejecucin de un programa:
break
watch
delete
info breakpoints
step
stepi
next
finish
continue
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
35
Para ejemplificar el uso de estos comandos, se proceder a depurar el programa
ejecutado en la seccin anterior. Esta vez se invocar al depurador pasando
como argumento el nombre del archivo ejecutable que se desea depurar, en
lugar de utilizar el comando file:
linux> gdb suma
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
36
Dado que se est recorriendo un arreglo de 8 elementos, y solo se van a sumar
aquellos almacenados en las posiciones impares, el ciclo debera ejecutarse tan
solo cuatro veces. A continuacin se proceder a comenzar la ejecucin del
programa con el comando run. Cada vez que se alcance la etiqueta ciclo, el
depurador detendr la ejecucin:
(gdb) run
Starting program: /root/suma
Reading symbols from shared object read from target memory...(no debugging symbols
found)...done.
Loaded system supplied DSO at 0x355000
(no debugging symbols found)
(no debugging symbols found)
Breakpoint 1, 0x08048188 in ciclo ()
(gdb)
Se utilizar el comando continue las veces que sea necesario para continuar
ejecutando el programa hasta alcanzar el final del mismo. Si se cuentan las
veces que se ejecut el ciclo, nos damos cuenta de que el mismo se est
ejecutando ocho veces (el punto de parada es alcanzado nueve veces, pero en
esta ltima la comparacin se evala como falsa y no se entra al ciclo), es decir,
que al parecer el programa est recorriendo todos los elementos del arreglo y
sumndolos.
Para verificar esto, se insertar un punto de parada del tipo watch, utilizando el
comando del mismo nombre, para verificar cuando (y como) es modificada la
variable suma (que se encuentra en el registro %eax. Tambin se eliminar el
breakpoint anterior ya que ha dejado de ser til. Note que antes de realizar
estas acciones reiniciaremos la ejecucin el programa (en este caso es posible
utilizar el comando run, pues sabemos que se detendr la primera vez que
alcance la etiqueta ciclo):
(gdb) run
Starting program: /root/suma
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
37
A partir de este momento se proceder de forma similar a como se hizo con el
punto de parada anterior, es decir, se utilizar el comando continue para
avanzar en la ejecucin y dejar que el depurador indique cuando el registro es
modificado. Si observa el programa original, notar que esto solo ocurre al
momento de sumar cada elemento del arreglo con el acumulador. Si nuestra
suposicin es correcta, y el problema del programa consiste en que se estn
sumando todos los elementos, el programa debera detenerse ocho veces, pues
el registro %eax ser modificado la misma cantidad de veces (una por cada
elemento sumado). Efectivamente:
(gdb) continue
Continuing.
Watchpoint 3: $eax
Old value = 0
New value = 1
0x08048199 in ciclo ()
(gdb) continue
Continuing.
Watchpoint 3: $eax
Old value = 1
New value = 11
0x08048199 in ciclo ()
(gdb) continue
Continuing.
Watchpoint 3: $eax
Old value = 11
New value = 3
0x08048199 in ciclo ()
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
38
ejecucin se detiene en este punto. En este caso deje el depurador tal cual, en la
prxima seccin continuaremos desde aqu.
Comandos bsicos de inspeccin
En la seccin anterior se ejecut dos veces el programa. En la primera se utiliz
un breakpoint, mientras que en la segunda se utiliz un watchpoint. Si algo
qued claro de esta pequea experiencia, es que el segundo mtodo fue mucho
ms til a la hora de sacar conclusiones y comprobar hechos, simplemente
porque proporcion ms informacin que el primero (en este caso, el valor del
registro %eax).
Una vez que la ejecucin del programa se encuentra detenida (sin importar el
tipo de punto de parada utilizado o el motivo por el que se detuvo la ejecucin)
es posible inspeccionar el estado del programa. Entre las cosas que pueden ser
inspeccionadas se encuentran los registros de la mquina (no solo los de
propsito general sino tambin los de propsito especfico como el eflags o el
eip), el contenido de la memoria, y la pila actual de llamadas.
A continuacin se muestra una breve descripcin de los comandos ms
comnmente utilizados en el depurador gdb para inspeccionar el estado de un
programa en ejecucin:
info registers
display
disassemble
info variables
info locals
backtrace
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
39
A continuacin se utilizarn algunos de estos comandos para comprobar que
efectivamente el ndice utilizado para recorrer el arreglo no se est actualizando
debidamente. Eliminamos el watchpoint anterior e insertamos un breakpoint en
la misma instruccin de suma (cuya direccin obtuvimos cada vez que la
ejecucin se detuvo al modificarse el registro %eax). La razn de hacer este
cambio es evitar que la ejecucin se detenga en cualquier otra parte del
programa en que se modifique %eax, como sucedi con el printf en la ejecucin
anterior:
(gdb) delete 3
(gdb) break *0x08048199
Breakpoint 4 at 0x8048199
ejecucin
actual
no
ha
finalizado
el
depurador solicitar
una
1
0
1
1716164
0xbfeaa1e0
0x0
-1075142164
134513028
0x8048199
514
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
40
Aqu se hace evidente el primer error: El ndice debera comenzar en uno, ya que
ste corresponde al primer elemento impar del arreglo. Sin embargo se observa
que el primer elemento que se carga es el que se encuentra en la posicin cero.
En este caso es el contenido del registro %edx (1), que es en donde se carg
previamente. Es posible utilizar el comando print para comprobar efectivamente
quienes son los elementos A[0], A[1] y A[%ecx] (este ltimo cargado en %edx)
(gdb) print *(&A+0)
$1 = 1
(gdb) print *(&A+1)
$2 = 10
(gdb) print *(&A+$ecx)
$3 = 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
41
Breakpoint 4, 0x08048199 in ciclo ()
11: *(&{<data variable, no debug info>} 134517372 + $ecx) = 14
10: $ecx = 4
set
display
jump
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
42
se
Note que el display que se haba insertado anteriormente (A[%ecx]) no pudo ser
procesado debido a que el valor original de %ecx ocasiona que la referencia a
memoria no sea vlida. El depurador automticamente deshabilitar este display
para los sucesivos puntos de parada que sean alcanzados. Es posible utilizar el
comando info display para comprobar cuales estn habilitados y cuales no
(observe la letra y o n que refleja este hecho):
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
43
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
44
En cualquier caso, lo importante es que luego de ejecutar las prximas dos
instrucciones el registro %ecx quedar inicializado en cero. En ese momento
corregiremos esto manualmente utilizando el comando set para inicializarlo en
uno:
(gdb) stepi 2
0x08048188 in ciclo ()
Observe que el registro %ecx comenz el ciclo con un valor de uno. Ahora vale
dos, despus de efectuarse la suma ocasionada por el primer display .
Posteriormente se ejecutar la instruccin que lo incrementaba en uno en el
programa original, con lo cual en la prxima iteracin del ciclo el registro
contendr el valor tres, luego cinco y as sucesivamente. Es decir, que los
cambios han funcionado.
Sin embargo, note que el display 11 (este nmero puede variar) indica que el
elemento cargado fue -8, que en realidad no es el elemento A[1] sino A[2]. No
se deje engaar, esto simplemente es consecuencia de que la expresin del
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
45
Efectivamente, el elemento A[1] es 10. Es posible dejar el display tal y como
est, y el resultado ser correcto ya que el mismo no afecta a la ejecucin del
programa. Sin embargo, conviene modificarlo para poder observar de forma
correcta el elemento cargado y el ndice utilizado en las iteraciones restantes:
(gdb) display $edx
13: $edx = 10
(gdb) display $ecx
14: $ecx = 2
(gdb) delete display 10
(gdb) delete display 11
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
14: y $ecx
13: y $edx
12: y $ecx = $ecx + 1
(gdb)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
46
Una vez que estamos seguros de los errores y de la efectividad de las soluciones
propuestas, podemos modificar las instrucciones adecuadas en el programa
original, no solo con la certeza de que al compilarlo de nuevo el programa
funcionar de forma adecuada, sino con el conocimiento de cual era el problema
y con una justificacin clara de porqu las modificaciones hechas han sido
exitosas.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
47
Veamos algunos ejemplos de la informacin adicional incluida mediante el uso
del comando g. En primer lugar, observe lo que ocurre al intentar utilizar los
comandos mostrados a continuacin con el programa que no contiene
informacin adicional:
[root@localhost ~]# gdb ejemplo2
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
..
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) list 4,7
No symbol table is loaded. Use the "file" command.
(gdb) info line 5
No symbol table is loaded. Use the "file" command.
(gdb) break main
Breakpoint 1 at 0x8048382
(gdb) run
Starting program: /root//ejemplo2
Reading symbols from shared object read from target memory...
(no debugging symbols found)...done.
Loaded system supplied DSO at 0x320000
(no debugging symbols found)
(no debugging symbols found)
Breakpoint 1, 0x08048382 in main ()
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
48
(gdb) run
Starting program: /root/ejemplo1
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x488000
Breakpoint 1, main () at ejemplo.c:5
5
printf("programa de ejemplo\n");
Note lo fcil que resulta relacionar las instrucciones de alto nivel con sus
correspondientes instrucciones en lenguaje de mquina utilizando el depurador.
Adems cada vez que el programa alcance un punto de parada, mostrar
informacin adicional referida al cdigo fuente original. Se deja al lector la tarea
de investigar que otros comandos adicionales provee gdb para ser utilizados
con aquellos archivos que contienen informacin de depuracin.
el
fin
de
poder aprender a
utilizar
de forma
efectiva
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
cualquier
49
Para finalizar, se enumeran algunos detalles del depurador gdb que son muy
tiles y permiten agilizar mucho el proceso de depuracin una vez que se ha
adquirido la prctica necesaria:
con
el
comando
stepi
luego
se
presiona
ENTER
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
50
Secciones
Un programa escrito en lenguaje ensamblador se compone de varias secciones.
Las secciones ms comunes son: la seccin de texto, la seccin de datos y la
seccin bss.
En la seccin de texto se escriben las instrucciones, en la seccin de datos los
datos inicializados y en la seccin bss las variables sin inicializar.
Cada una de las secciones se declara por medio de una directiva. Para declarar
las secciones mencionadas se usan las siguientes directivas:
.section .text para la seccin de texto (instrucciones)
.section .data para la seccin de datos (datos inicializados)
.section .bss
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
51
Las siglas bss corresponden a "block storage start", que significa inicio de
bloque de almacenamiento.
La ventaja de declarar variables en la seccin .bss es que esos datos no se
incluyen en el programa ejecutable y por lo tanto el tamao total del programa
es menor al tamao generado por la declaracin equivalente en la seccin .data.
A diferencia de las secciones de datos y bss, la seccin de texto es de solo
lectura. Esto quiere decir que la misma no puede ser modificada en tiempo de
ejecucin. El propsito de esto consiste en que si existen mltiples instancias
del programa ejecutndose, todas comparten la misma seccin de texto (se
carga una sola vez en memoria), mientras que cada una tiene su propia seccin
de datos y/o bss.
Sin embargo, existen datos dentro de un programa que nunca son modificados,
tales como las constantes, o los literales no asociados a una variable (como la
cadena Hola Mundo utilizada en la llamada a printf en el captulo anterior).
Con el fin de compartir estos datos de la misma forma que ocurre con las
instrucciones, los mismos pueden ser almacenados dentro de una seccin
especial llamada rodata (Read Only Data, Datos de solo lectura). La misma se
comporta de la misma forma que la seccin de datos, pero no permite
operaciones de escritura sobre los datos declarados dentro de la misma.
Punto de inicio
Cuando se realiza la traduccin del programa en lenguaje ensamblador a un
archivo ejecutable, el enlazador necesita saber el punto de inicio en el cdigo.
Para ello se declara una etiqueta: _start la cual indica a partir de qu instruccin
se comienza a ejecutar el cdigo.
Esta etiqueta debe ser declarada como global, es decir, que est disponible para
aplicaciones externas; esto se logra utilizando la directiva .globl.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
52
La finalizacin se realiza de la siguiente manera:
movl $1, %eax
movl $0, %ebx
int $0x80
Estructura general
En general la estructura de un programa en lenguaje ensamblador tiene la
siguiente forma:
.section .data
# aqui se declaran variables inicializadas
.section .bss
# aqui van las variables declaradas pero sin inicializar
.section .text
.globl _start
_start:
# esta etiqueta indica el inicio del programa principal
# aqui van las instrucciones
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
53
Tipo de dato
cadena de caracteres
cadena de caracteres con caracter de culminacin (null)
equivalente a .asciz
valor de un byte (8 bits)
nmero de punto flotante precisin doble (64 bits)
nmero de punto flotante precisin simple (32 bits)
nmero entero de 4 bytes (32 bits)
equivalente a .long
nmero entero de 16 bytes
nmero entero de 8 bytes (64 bits)
nmero entero de 2 bytes (16 bits)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
54
Se pueden definir mltiples valores en la misma lnea. Cada uno de ellos ser
guardado en memoria en el orden en el cual fueron declarados.
Ejemplo: declaracin de mltiples valores con una misma etiqueta
.section .data
var: .long 10, 20, 30, 40, 50
En este caso cuando se lee la variable var arroja el valor 10, para poder leer el
siguiente valor se debe incrementar la direccin de var en 4 bytes (debido a que
la variable est declarada como long, es decir de 32 bits) de esta manera se usa
la etiqueta var como la direccin inicial de estos valores y su tratamiento es el
de un arreglo donde cada acceso se realiza tomando var como posicin inicial
lo cual sera equivalente a decir var[0] y las posiciones siguientes como un
desplazamiento de 4 bytes cada uno. Para leer por ejemplo el valor 30 se accede
como var+8.
Cuando se definen las variables el sistema las guarda en forma consecutiva en
memoria. Por ejemplo si se definen variables de 16 bits y luego se leen usando
instrucciones de 32 bits el sistema no produce un mensaje de error y accede los
bytes consecutivos leyendo datos no vlidos.
Estas directivas tambin se pueden utilizar en la seccin .rodata la cual es de
solo lectura tomando en consideracin que los valores de las variables no
podrn ser modificados.
Definicin de constantes
Las constantes se pueden definir en cualquier parte del programa, sin embargo
se recomienda hacerlo en la seccin de definicin de datos (.data o .rodata) por
claridad del programa. La definicin de constantes se hace usando la directiva
.equ, el formato para esta directiva es:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
55
Cuando se declara una constante su valor no puede ser modificado por el
programa. Esta declaracin "nombra" el valor 32 como escala. La constante se
puede utilizar como un inmediato, como desplazamiento o como direccin de
memoria. Cuando se usa como un inmediato se debe anteponer un smbolo de
dlar, en este caso para usar escala como inmediato se coloca: $escala.
Descripcin
declara un rea de memoria para datos sin inicializar
equivalente a .comm
declara un rea local de memoria para datos sin inicializar
La directiva .lcomm se usa para datos locales, que no sern usados fuera del
cdigo local.
El formato, para estas directivas es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
56
Captulo 5. Instrucciones
Las instrucciones en gas tienen un sufijo que indica el tamao del dato sobre el
cual acta la instruccin.
Sufijo
b
w
l
Tamao
byte
word (2 bytes)
long (4 bytes)
Expresin
$inm
reg
Inm
(reg)
Inm(reg)
(regb, regi)
Inm(regb, regi)
(, regi, e)
Inm(, regi, e)
(regb, regi, e)
Inm(regb, regi, e)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
57
Ejemplo: valores
para
cada
modo
de
direccionamiento, asumiendo
los
y %ecx= 0x10
Ejemplo
$0x65
%eax
0x120
(%eax)
8(%eax)
(%eax, %ecx)
8(%eax, %ecx)
(, %eax, 4)
8(, %eax, 4)
(%eax, %ecx, 2)
12(%eax, %ecx, 2)
Valor
0x65
0x100
M[0x120]
M[0x100]
M[0x108]
M[0x110]
M[0x118]
M[0x400]
M[0x408]
M[0x120]
M[0x12C]
Expresin
M[12+contenido de %eax]
M[0xC+contenido de %eax]
Valor
M[0x10C]
M[0x10C]
Efecto
DestinoFuente
Descripcin
mueve 1 byte
DestinoFuente
mueve 2 bytes
DestinoFuente
mueve 4 bytes
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
movl $25, %eax
movb $10, etiqueta
movw %bx, %ax
movl %eax, etiqueta
movl etiqueta, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
58
Movimiento de datos inmediatos a registro o a memoria
Los datos inmediatos se especifican directamente en la instruccin. Deben estar
precedidos por el smbolo dlar para indicar que son datos inmediatos. Pueden
estar expresados en decimal o hexadecimal.
Ejemplos:
movb
movw
movl
movl
movl
$45, %ah
$123, %ax
$85, %eax
$5678, %eax
$0x100, %ebx
#
#
#
#
#
movl
movl
$12, 0x100
$12, a
#
#
#
#
#
#
%ah, %bl
%ax, %bx
%eax, %ebx
%eax, a
a, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
59
Movimiento de datos con extensin
Hay dos instrucciones adicionales que permiten mover datos extendindolos.
Instruccin
movsbl Fuente, Destino
Efecto
Destino Fuente (signo extendido)
Descripcin
mueve un byte signo extendido
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
Ejemplo
movsbl %bx, %eax
movzbl %eax, etiqueta
movsbl etiqueta, %eax
Ejemplo de movzbl:
movzbl %bl, %eax
memoria
Efecto
Destino<- direccin de Fuente
Operandos Vlidos
registro
Descripcin
Carga la direccin efectiva
Ejemplo
leal etiqueta, %eax
Ejemplo:
leal a, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
60
Programa de ejemplo con varios movimientos de datos.
.section
a: .long
b: .long
c: .long
.data
25
42
5
# a=25
# b=42
# c=5
.section .text
.globl _start
_start:
movl a, %eax
movl b, %ebx
movl c, %ecx
movl %ecx, %eax
movl %eax, a
leal a, %ecx
movl %ebx, (%ecx)
movl $a, %ecx
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
%eax=a=25
%ebx=b=42
%ecx=c=5
%eax=%ecx=5
a=%eax=5
%ecx=direccin de a
a=%ebx=42
%ecx=direccin de a
finalizacin del programa
Uso de la pila
La pila es un rea de memoria que crece desde una direccin inicial hacia
direcciones menores. El ltimo elemento colocado en la pila es el que est
disponible para ser retirado.
Las instrucciones para el manejo de la pila son dos, una para apilar un operando
fuente y una para desapilar el valor que est en el tope de la pila y colocarlo en
un operando destino.
Instruccin push (apilar)
Instruccin
pushw Fuente
Efecto
R[%esp] R[%esp]-2
M[R[%esp]] Fuente
pushl Fuente
R[%esp] R[%esp]-4
M[R[%esp]] Fuente
Operandos Vlidos
inmediato
registro
memoria
Descripcin
Actualiza el apuntador %esp y luego
coloca Fuente en el tope de la pila (2 bytes)
Actualiza el apuntador %esp y luego
coloca Fuente en el tope de la pila (4 bytes)
Ejemplo
pushw $7
pushl %eax
pushl etiqueta
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
61
Instruccin pop (desapilar)
Instruccin
popw Destino
Efecto
Descripcin
lee el valor del tope de la pila, lo guarda en Destino y
luego actualiza %esp (dato de 2 bytes)
Destino M[R[%esp]]
R[%esp] R[%esp]+2
popl Destino
Destino M[R[%esp]]
R[%esp] R[%esp]+4
Operandos Vlidos
registro
memoria
Ejemplo
popw %ax
popl etiqueta
%eax=15
%ebx=43
%ecx=28
pushl %eax
pushl %ebx
popl %eax
pushl %ecx
popl %ebx
popl %ecx
Ocurre lo siguiente:
1
2
3
4
5
6
pushl %eax
pushl %ebx
popl %eax
pushl %ecx
popl %ebx
popl %ecx
%esp=%esp-4
%esp=%esp-4
%eax= M[%esp]
%esp=%esp-4
%ebx= M[%esp]
%ecx= M[%esp]
%esp=0x104
%esp=0x100
%eax=M[0x100]
%esp=0x100
%ebx=M[0x100]
%ecx=M[0x104]
M[%esp]=%eax
M[%esp]=%ebx
%eax=43
M[%esp]=%ecx
%ebx=28
%ecx=15
M[0x104]=15
M[0x100]=43
%esp=%esp+4
M[0x100]=28
%esp=%esp+4
%esp=%esp+4
%esp=104
%esp=104
%esp=108
2:pushl %ebx
%esp
%esp
0x104
0x108
15
4:pushl %ecx
%esp
0x100
0x104
0x108
28
15
0x100
0x104
0x108
43
15
3: popl %eax
%esp
0x100
0x104
0x108
5:popl %ebx
%esp
0x100
0x104
0x108
43
15
6: popl %ecx
28
15
%esp
0x100
0x104
0x108
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
28
15
62
se
ejecutan
estas
instrucciones
las
banderas
son
actualizadas
automticamente.
add (suma)
Instruccin
addb Fuente, Destino
Efecto
DestinoDestino + Fuente
Descripcin
suma operandos de 1 byte
DestinoDestino + Fuente
DestinoDestino + Fuente
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
addl $15, %eax
addb $10, etiqueta
addw %bx, %ax
addl %eax, etiqueta
addl etiqueta, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
63
sub (resta)
Instruccin
subb Fuente, Destino
Efecto
DestinoDestino - Fuente
Descripcin
resta operandos de 1 byte
DestinoDestino - Fuente
DestinoDestino - Fuente
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
subl $15, %eax
subb $10, etiqueta
subw %bx, %ax
subl %eax, etiqueta
subl etiqueta, %eax
inc (incremento)
Instruccin
incb Destino
Efecto
DestinoDestino + 1
Descripcin
incrementa operando de 1 byte
incw Destino
DestinoDestino + 1
incl Destino
DestinoDestino + 1
Operandos Vlidos
registro
memoria
Ejemplo
incw %ax
incl etiqueta
dec (decremento)
Instruccin
decb Destino
Efecto
DestinoDestino - 1
Descripcin
decrementa operando de 1 byte
decw Destino
DestinoDestino - 1
decl Destino
DestinoDestino - 1
Operandos Vlidos
registro
memoria
Ejemplo
decw %ax
decl etiqueta
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
64
neg (negacin aritmtica)
Esta instruccin cambia el signo del operando para ello realiza el complemento
a 2 del nmero.
Instruccin
negb Operando
Efecto
Operando - Operando
Descripcin
niega operando de 1 byte
negw Operando
Operando - Operando
negl Operando
Operando - Operando
Operandos Vlidos
registro
memoria
Ejemplo
negl %eax
negl etiqueta
Efecto
Operando ~ Operando
Descripcin
niega operando de 1 byte
notw Operando
Operando ~ Operando
notl Operando
Operando ~ Operando
Operandos Vlidos
registro
memoria
Ejemplo
notl %eax
notl etiqueta
and (y lgico)
Esta instruccin ejecuta un and bit a bit entre los operandos. La operacin lgica
and se define como:
Operando 1
Operando 2
AND
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
65
Instruccin
andb Fuente, Destino
Efecto
DestinoDestino AND Fuente
Descripcin
and entre operandos de 1 byte
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
andl $15, %eax
andb $10, etiqueta
andw %bx, %ax
andl %eax, etiqueta
andl etiqueta, %eax
or (o lgico)
Esta instruccin realiza un or bit a bit entre los operandos. La operacin lgica
or se define como:
Operando 1
Operando 2
OR
Instruccin
orb Fuente, Destino
Efecto
DestinoDestino OR Fuente
Descripcin
or entre operandos de 1 byte
DestinoDestino OR Fuente
DestinoDestino OR Fuente
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
orl $15, %eax
orb $10, etiqueta
orw %bx, %ax
orl %eax, etiqueta
orl etiqueta, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
66
xor (or exclusivo)
Esta instruccin realiza un or exclusivo bit a bit entre los operandos. La
operacin lgica xor se define como:
Operando 1
Operando 2
XOR
Instruccin
xorb Fuente, Destino
Efecto
DestinoDestino XOR Fuente
Descripcin
xor entre operandos de 1 byte
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Ejemplo
xorl $15, %eax
xorb $10, etiqueta
xorw %bx, %ax
xorl %eax, etiqueta
xorl etiqueta, %eax
# %eax=0
Ya que el xor produce un cero cuando los bits son iguales, esta operacin
siempre producir un registro con contenido cero.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
67
Instruccin
shlb Posiciones, Destino
Efecto
DestinoDestino << posiciones
Descripcin
desplazamiento a la izquierda, operando de 1 byte
inmediato
inmediato
%cl
%cl
Operandos Vlidos
registro
memoria
registro
memoria
Ejemplo
shll $4, %eax
shlb $4, etiqueta
shll %cl, %eax
shll %cl, etiqueta
Efecto
DestinoDestino >> posiciones
Descripcin
desplazamiento lgico a la derecha, operando de 1 byte
inmediato
inmediato
%cl
%cl
Operandos Vlidos
registro
memoria
registro
memoria
Ejemplo
shrl $4, %eax
shrb $4, etiqueta
shrl %cl, %eax
shrl %cl, etiqueta
Efecto
DestinoDestino >> posiciones
Descripcin
desplazamiento aritmtico a la derecha, operando de 1 byte
inmediato
inmediato
%cl
%cl
Operandos Vlidos
registro
memoria
registro
memoria
Ejemplo
sarl $4, %eax
sarb $4, etiqueta
sarl %cl, %eax
sarl %cl, etiqueta
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
68
mul (multiplicacin de enteros sin signo)
Esta instruccin opera sobre nmeros sin signo.
Instruccin
mulb Fuente
Efecto
%ax Fuente * %al
Descripcin
multiplicacin sin signo, %al implcito
mulw Fuente
mull Fuente
Operandos Vlidos
registro
memoria
Ejemplo
mulw %cx
En este caso el resultado queda en %dx:%ax
mull etiqueta En este caso el resultado queda en %edx:%eax
Efecto
%ax Fuente * %al
Descripcin
multiplicacin con signo, 1 byte. %al implcito
imulw Fuente
imull Fuente
Operandos Vlidos
registro
memoria
Ejemplo
imulw %cx
En este caso el resultado queda en %dx:%ax
imull etiqueta En este caso el resultado queda en %edx:%eax
Efecto
Destino Destino * Fuente
Descripcin
multiplicacin con signo, dos operandos de 2 bytes
registro
inmediato
memoria
Operandos Vlidos
registro
registro
registro
Ejemplo
imulw %cx, %bx
imull $4, %eax
imull etiqueta, %ebx
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
69
imul con tres operandos
En esta instruccin el primer operando es un inmediato y el destino debe ser un
registro.
Instruccin
imulw Multiplicador, Fuente, Destino
Efecto
Destino Fuente * Multiplicador
Descripcin
multiplicacin con un inmediato, 2 bytes
inmediato
inmediato
Operandos Vlidos
registro
registro
memoria
registro
Ejemplo
imulw $12, %ax, %bx
imull $12, etiqueta, %ecx
Efecto
%dx:%ax %ax con signo extendido
Descripcin
extiende palabra a doble palabra
Efecto
%edx:%eax %eax con signo extendido
Descripcin
extiende palabra doble a palabra cudruple
Efecto
%al %ax Fuente
Descripcin
divisin sin signo, 1 byte , %ax implcito
%ah resto
divw Fuente
%dx resto
divl Fuente
%edx resto
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
70
Operandos Vlidos
registro
memoria
Ejemplo
divw %cx
En este caso el resultado queda en %ax
divl etiqueta En este caso el resultado queda en %eax
%dx:%ax implcito
%edx:%eax implcito
Efecto
Descripcin
divisin con signo, 1 byte, %ax implcito
idivw Fuente
idivl Fuente
Operandos Vlidos
registro
memoria
Ejemplo
idivw %cx
En este caso el resultado queda en %ax
idivl etiqueta En este caso el resultado queda en %eax
%dx:%ax implcito
%edx:%eax implcito
.data
5
45
6
.section .text
.globl _start
_start:
movl a, %eax
movl b, %ebx
addl %ebx, %eax
decl %eax
movl c, %ecx
cltd
idivl %ecx
subl %edx, %ebx
imull $5, %ebx
imull %ebx
imull $3,%eax,%ecx
decl %eax
subl $1755, %eax
shll $2, %eax
movl $32, %ebx
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
%eax=a=5
%ebx=b=45
%eax=%eax+%ebx=5+45=50
%eax=%eax-1=49
%ecx=c=6
extiende %eax a %edx:%eax
%eax=%eax/%ecx=49/6=8 %edx=resto=1
%ebx=%ebx-%edx=45-1=44
%ebx=%ebx*5=44*5=220
%edx:%eax=%eax*%ebx %eax=8*220=1760
%ecx=%eax*3=1760*3=5280
%eax=%eax-1=1759
%eax=%eax-1755=4
%eax=%eax<<2 = %eax*22 %eax=16
%ebx=32
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
71
sarl $4, %ebx
Instrucciones de comparacin
cmp (compara)
Compara el contenido de dos operandos. Resta los operandos pero no actualiza
el resultado, solo actualiza las banderas.
Instruccin
cmpb Operando2, Operando1
cmpw Operando2, Operando1
cmpl Operando2, Operando1
inmediato
inmediato
registro
registro
memoria
Efecto
Operando1 - Operando2
Operando1 - Operando2
Operando1 - Operando2
Operandos Vlidos
registro
memoria
registro
memoria
registro
Descripcin
Compara los operandos de 1 byte
Compara los operandos de 2 bytes
Compara los operandos de 4 bytes
Ejemplo
cmpl $5, %eax
cmpb $4, etiqueta
cmpw %bx, %ax
cmpl %eax, etiqueta
cmpl etiqueta, %eax
inmediato
inmediato
registro
registro
memoria
Operandos Vlidos
registro
memoria
registro
memoria
registro
Efecto
Operando1 AND Operando2
Operando1 AND Operando2
Operando1 AND Operando2
Descripcin
Examina los operandos de 1 byte
Examina los operandos de 2 bytes
Examina los operandos de 4 bytes
Ejemplo
testl $5, %eax
testb $4, etiqueta
testw %bx, %ax
testl %eax, etiqueta
testl etiqueta, %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
72
Es comn usar la instruccin test repitiendo el operando para saber si este es
cero, positivo o negativo.
Ejemplo:
testl
%eax, %eax
Instrucciones de salto
Una instruccin de salto produce un cambio en la ejecucin del programa
pasando a una nueva posicin, no secuencial. La direccin del salto se
representa con una etiqueta.
Instruccin
jmp etiqueta
jmp *etiqueta
ja etiqueta
jna etiqueta
jae etiqueta
jnae etiqueta
jb etiqueta
jnb etiqueta
jbe etiqueta
jnbe etiqueta
jc etiqueta
jnc etiqueta
jcxz etiqueta
jecxz etiqueta
je etiqueta
jne etiqueta
jg etiqueta
jng etiqueta
jge etiqueta
jnge etiqueta
jl
etiqueta
jnl etiqueta
jle etiqueta
jnle etiqueta
js etiqueta
jns etiqueta
jo etiqueta
jno etiqueta
jp etiqueta
jnp etiqueta
jpe etiqueta
jpo etiqueta
Descripcin
Salto incondicional directo
Salto incondicional indirecto
Salto por superior (nmeros sin signo)
Salto por no superior (nmeros sin signo)
Salto por superior o igual (nmeros sin signo)
Salto por no superior o igual (nmeros sin signo)
Salto por inferior (nmeros sin signo)
Salto por no inferior (nmeros sin signo)
Salto por inferior o igual (nmeros sin signo)
Salto por no inferior o igual (nmeros sin signo)
Salto por acarreo (nmeros sin signo)
Salto por no acarreo (nmeros sin signo)
Salto por %cx=0
Salto por %ecx=0
Salto por igual
Salto por no igual
Salto por mayor (>)
Salto por no mayor
Salto por mayor o igual (>=)
Salto por no mayor o igual
Salto por menor (<)
Salto por no menor
Salto por menor o igual (<=)
Salto por no menor o igual
Salto por negativo
Salto por no negativo
Salto por desbordamiento
Salto por no desbordamiento
Salto por paridad
Salto por no paridad
Salto por paridad par
Salto por paridad impar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
73
la etiqueta o indirecto donde la direccin de destino se lee de un registro o de
una posicin de memoria.
Ejemplo de salto incondicional directo:
1
2
3
4
etiq1:
addl
jmp
subl
addl
%eax, %ebx
etiq1
%edx, %ebx
%edx, %ebx
*%eax
jmp
*(%eax)
menor:
fin:
movl
movl
cmpl
jl
subl
jmp
addl
valor1, %eax
valor2, %ebx
%ebx, %eax
menor
$5,%eax
fin
$5,%eax
#
#
#
#
#
#
#
%eax=valor1
%ebx=valor2
compara valor1 con valor2
si valor1<valor2 salta a etiq1
si valor1>=valor2 resta 5 a %eax
salta a fin
si valor1<valor2 suma 5 a %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
74
ejecutara la suma lo cual arrojara un resultado errneo. En este programa slo
se ejecuta una de las dos operaciones aritmticas, la resta en caso de cumplirse
la condicin o la suma en caso de que no se cumpla.
condicin
(tal
como
estn
expresadas
en
los
saltos).
Estas
%ebx, %edx
%cl
test %eax,%eax
setz %bl
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
75
l1
l2
l3
l4
l5
l6
l7
l8
l9
l10
l11
l12
%eax
14
%ebx
%ecx
%edx
4
0
1
5
70
4
8
0
2
17
1
0
La instruccin loop
La instruccin loop permite programar ciclos de manera eficiente.
Instruccin
loop etiqueta
loope etiqueta
loopz etiqueta
loopne etiqueta
loopnz etiqueta
Descripcin
Ciclo hasta que %ecx=0
Ciclo hasta que %ecx=0 o la bandera de cero (ZF)=0
Equivalente a loope
Ciclo hasta que %ecx=0 o la bandera de cero (ZF)=1
Equivalente a a loopne
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
76
ciclo1:
# suma 5
# regresa al inicio del ciclo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
77
Ejercicios
5.1- Muestre los cambios ocurridos en los contenidos de los registros para el
siguiente programa:
.section .text
.globl _start
_start:
movl $5, %eax
xorl %ecx, %ecx
addl $6, %ecx
addl %ecx, %eax
movl %ecx, %ebx
movl $2, %edx
incl %ebx
imull %edx, %ebx
shll $2,%edx
sarl $1,%ecx
addl %ebx, %eax
cltd
idivl %ecx
movl $1, %eax
movl $0, %ebx
int $0x80
5.2- Para los valores a=6, b=8, c=12, d=4 declarados en la seccin de datos,
escriba un programa que calcule x=a-3b+25(c-d).
5.3- Escriba un fragmento de cdigo que calcule x=16*y sin utilizar la
instruccin de multiplicacin.
5.4- Escriba un fragmento de cdigo que calcule x=y/32 sin usar la instruccin
de divisin.
5.5- Dados los valores a=4, b=5, c=2, d=7 declarados en la seccin de datos;
escriba un programa que calcule la expresin x=(a+(b-c))/(c*d).
5.6- Escriba un programa que dados tres valores enteros declarados en la
seccin de datos, determine el mayor y lo guarde en una variable denominada
mayor.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
78
5.7- Escriba un programa que dados dos valores enteros a y b declarados en la
seccin de datos produzca como salida la actualizacin de la variable resultado
segn las siguientes condiciones:
Si a=b: resultado=a
Si a>b: resultado=a-b
Si a<b: resultado=b-a
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
79
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
80
Los conceptos de archivo y flujo estn relacionados de la siguiente manera: Un
archivo es asociado a un flujo determinado mediante una operacin denominada
apertura. A partir de este momento, el programador enva o recibe datos hacia o
desde el flujo (que puede ser binario o de texto), y es el subsistema de E/S
quien realiza la correspondencia necesaria entre dicho flujo y su archivo
asociado, de forma que los datos sean efectivamente intercambiados con el
dispositivo fsico que dicho archivo representa. Finalmente es posible desasociar
el flujo del archivo mediante una operacin de cierre.
En un programa que no involucre operaciones avanzadas de E/S, (como la
mayor parte de los presentados en esta obra) el programador no necesita
realizar operaciones de apertura o cierre, ya que al momento de comenzar la
ejecucin del programa existen ciertos flujos asociados automticamente a los
dispositivos de E/S utilizados con mayor frecuencia. El estndar ANSI de C
define tres flujos predefinidos:
Flujo
Descripcin
stdin
Entrada estndar
Teclado
stdout
Salida estndar
Monitor
stderr
Flujo de errores
Monitor
Funcin printf
La funcin printf permite escribir en la salida estndar, proporcionando un
formato especfico para los datos a escribir. De all que las escrituras realizadas
por esta funcin y las lecturas realizadas por scanf sean conocidas como e/s
formateada. Esto implica que ambas funciones pueden trabajar con los tipos de
datos especificados por el estandar ANSI de C tales como nmeros, caracteres y
cadenas.
Esta funcin recibe una cantidad variable de argumentos, en los que solo uno de
ellos es obligatorio: la cadena de formato. Este parmetro es una cadena que
permite indicar el formato que tendr la impresin que se quiere realizar, y en
base a la cual se determina la cantidad y tipo de los parmetros restantes.
Dicha cadena puede contenter caracteres comunes y corrientes, los cuales se
mostrarn en pantalla exactamente como se encuentran en la cadena, y un
segundo tipo de caracteres conocidos como especificadores de formato , los
cuales estn formados por un smbolo de porcentaje (%) y un cdigo de formato
(c para caracteres, d para nmeros decimales, etc). Los especificadores de
formato compatibles con la funcin printf son los siguientes:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
81
Especificador
Formato
%c
Caracter simple
%d
%i
%e
%E
%f
%g
%G
%o
%p
%s
Cadena de caracteres
%u
%x
%X
Funcin scanf
La funcin scanf permite leer desde la entrada estndar, proporcionando un
formato especfico para los datos a recibir. De forma anloga a la funcin printf,
esta funcin permite reconocer los tipos de datos especificados por el estndar
ANSI de C tales como nmeros, caracteres y cadenas.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
82
Los argumentos recibidos por la funcin scanf son similares a los de la funcin
printf , siendo de nuevo el primero de ellos la cadena de formato. Sin embargo
en este caso la cadena de formato es utilizada para especificar una plantilla
que deber ser completada con la entrada proporcionada por el usuario.
En este caso, por cada especificador de formato que se encuentre en la cadena
ser necesario proporcionar un apuntador a la direccin de memoria en la que
ser almacenado el elemento reconocido. Los especificadores de formato
compatibles con la funcin scanf son los siguientes:
Especificador
Formato
%c
Caracter simple
%d
%i
%e
%E
%f
%g
%G
%o
%p
%s
Cadena de caracteres
%u
%x
%X
De esta forma, las siguientes llamadas a scanf son vlidas (asumiendo que la
variable edad ha sido declarada como entero, y las variables nombre y apellido
como arreglo de caracteres):
scanf("%d", &edad);
scanf(%s,%s, nombre, apellido);
Por ejemplo, la ejecucin de la primera llamada a scanf ocasionar que se
detenga la ejecucin del programa hasta que el usuario proporcione un nmero
entero decimal mediante la utilizacin del teclado. Si el usuario introduce,
digamos, el valor 20, el mismo ser asignado a la variable edad, o en otras
palabras, dicho valor ser almacenado en la direccin de memoria ocupada por
dicha variable (&edad).
Es vlido preguntarse que ocurre si la entrada del usuario no coincide al 100%
con la especificada por la cadena de formato al hacer una llamada a la funcin
scanf. De suceder esto, solo se reconoce la entrada hasta el primer caracter que
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
83
no coincida con la cadena de formato, y solo se le asigna un valor a las variables
correspondientes a los especificadotes de formato que preceden a dicho
carcter. En cualquier caso la funcin retorna la cantidad de elementos de la
entrada que fueron asignados a las variables. Por ejemplo, si se hace la
siguiente llamada a scanf:
scanf("%s, %s. V-%d", apellido, nombre, &cedula);
Y el usuario introduce la cadena Perez, Pedro. 16247521, la funcin scanf
devolver el valor 2, ya que la cadena coincide con la plantilla solo hasta el
espacio que se encuentra despus del punto. Al no encontrar la letra V, la
funcin no contina examinando la cadena de entrada, y retorna el valor dos ya
que solo las variables apellido y nombre recibieron un valor (Perez y Pedro,
respectivamente). La variable cdula no es modificada.
Consideraciones adicionales
Una diferencia importante entre las funciones printf y scanf consiste en la
manera en que se les pasan los argumentos. Todos los argumentos de una
llamada a la funcin scanf (a excepcin de la cadena de formato) son pasados
por referencia, es decir, se proporciona la direccin de la variable y no su valor.
Esto se debe a que la funcin utiliza estas variables para almacenar un valor
leido de la entrada estndar y en consecuencia necesita saber la posicin de
memoria en la que el mismo ser almacenado.
En contraparte, la funcin printf no necesita conocer la direccin de las
variables, sino el valor que contienen para poder escribirlo en la salida estndar.
Por esta razn, todos los tipos de dato simple (enteros, caracteres, etc.) son
pasados por valor. Algunas otras variables como los arreglos y las estructuras
(esto incluye las cadenas ya que son arreglos de caracteres) son pasados por
referencia, pero esto se debe a limitaciones del pase de parmetros por valor (ya
que los parmetros se almacenan en la pila, vase el captulo de
procedimientos) y no a que la funcin printf necesite conocer la direccin de
dichos argumentos per se.
Para ilustrar la utilizacin de ambas funciones desde un programa en lenguaje
ensamblador, se presentan dos ejemplos sencillos. Sin embargo es importante
hacer una acotacin en este punto. Cuando se hace una llamada a las funciones
printf y scanf (o a cualquier otro procedimiento), el contenido de los registros
%eax, %ecx y %edx corre el riesgo de ser modificado. El motivo de esto ser
explicado en profundidad en el capitulo relativo a la llamada a procedimientos,
sin embargo, es importante tener en cuenta este hecho al momento de
programar, tomando las precauciones necesarias para no perder informacin
importante al llevar a cabo las operaciones de lectura o escritura.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
84
El primer ejemplo consiste en un programa que pide al usuario una cadena de
caracteres mediante la utilizacin de scanf, y luego la muestra de nuevo
mediante la utilizacin de printf.
Programa en C:
#include <stdio.h>
char cadena[80];
main()
{
printf("Por favor introduzca una cadena: ");
scanf("%s", cadena);
printf("La cadena introducida es: %s\n", cadena);
}
Programa en ensamblador:
.section .rodata
cad1:
.asciz "Por favor introduzca una cadena: "
cad2:
.asciz "%s"
cad3:
.asciz "La cadena introducida es: %s\n"
.section .bss
cadena: .space 50
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando que se escriba una cadena
leal cad1, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad1)
call printf
# Hace la llamada a printf
addl $4, %esp
# Libera el espacio de la pila ocupado por
el nico argumento
# Lee la cadena introducida por el usuario
leal cadena, %eax
# Carga la direccin donde se almacenar
la cadena
pushl %eax
# Pasa el segundo argumento (cadena)
leal cad2, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad2)
call scanf
# Hace la llamada a scanf
addl $8, %esp
# Libera los 8 bytes de pila ocupados por
los argumentos
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
85
# Muestra el resultado
leal cadena, %eax
# Carga la direccin de la cadena leida
pushl %eax
# Pasa el segundo argumento (cadena)
leal cad3, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad3)
call printf
# Hace la llamada a printf
addl $8, %esp
# Libera los 8 bytes de pila ocupados por
los argumentos
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
86
cad3:
cad4:
.section .bss
A: .space 4
B: .space 4
C: .space 4
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando el valor de A
leal cad1, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasamel primer argumento (cad1)
call printf
# Hace la llamada a printf
addl $4, %esp
# Libera los 4 bytes de pila ocupados por el
nico argumento
# Lee el valor de A
leal A, %eax
# Carga la direccin donde se almacenar el
entero
pushl %eax
# Pasa el segundo argumento (&A)
leal cad4, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad4)
call scanf
# Hace la llamada a scanf
addl $8, %esp
# Libera los 8 bytes de pila ocupados los
argumentos
# Muestra un mensaje solicitando el valor de B
leal cad2, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad2)
call printf
# Hace la llamada a printf
addl $4, %esp
# Libera los 4 bytes de pila ocupados por el
nico argumento
# Lee el valor de B
leal B, %eax
# Carga la direccin donde se almacenar el
entero
pushl %eax
# Pasam el segundo argumento (&B)
leal cad4, %eax
# Carga la direccin de la cadena de formato
pushl %eax
# Pasa el primer argumento (cad4)
call scanf
# Hace la llamada a scanf
addl $8, %esp
# Libera los 8 bytes de pila ocupados los
argumentos
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
87
# Suma los nmeros y deja el resultado en C
movl A, %eax
addl B, %eax
movl %eax, C
# Muestra el resultado
pushl C
# Pasamos el segundo argumento (C)
leal cad3, %eax
# Cargamos la direccin de la cadena de formato
pushl %eax
# Pasamos el primer argumento (cad3)
call printf
# Hacemos la llamada a printf
addl $8, %esp
# Liberamos los 8 bytes de pila ocupados los
argumentos
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80.rodata
Llamadas al sistema
Las llamadas al sistema son servicios que provee el sistema operativo a los
programas de usuario para llevar a cabo diversas tareas de manera controlada y
coordinada. En Linux, la lista de las distintas llamadas al sistema se puede
encontrar en el archivo unistd.h, generalmente ubicado en el directorio
/usr/include/asm/. De esta forma, es posible conocer el nmero que identifica
a cada servicio mediante el siguiente comando:
linux>
more /usr/include/asm/unistd.h
....
#define __NR_restart_syscall
#define __NR_exit
#define __NR_fork
#define __NR_read
#define __NR_write
#define __NR_open
#define __NR_close
....
0
1
2
3
4
5
6
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
88
linux>
man 2 write
Son de particular inters los servicios read (lectura) y write (escritura), los cuales
permiten realizar las mismas operaciones bsicas que las instrucciones de alto
nivel printf y scanf , pero a un nivel ms elemental. Si bien las llamadas al
sistema no son invocadas como funciones de C, a menudo la descripcin de las
mismas se da en la notacin de dicho lenguaje.
Servicio read
El prototipo del servicio read es el siguiente:
ssize_t read(int fd, void *buf, size_t count);
fd:
Descriptor de archivo desde el que se lee (stdin, stdout, sterr)
buf:
Apuntador al rea de memoria donde se almacenarn los datos.
count: Nmero mximo de bytes a leer.
Servicio write
De forma similar, el prototipo del servicio write es el siguiente:
ssize_t write(int fd, const void *buf, size_t num);
fd:
buf:
num:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
89
servicios read y write, es necesario colocar el descriptor de archivo desde el cual
se va a leer o al cual se va a escribir (fd) en el registro %ebx.
En caso de existir seis o ms argumentos, todos deben ser almacenados en un
rea de memoria contigua, y debe colocarse en %ebx un apuntador al primero
de los mismos.
Para ilustrar la utilizacin de las llamadas al sistema read y write, se presentan
de nuevo los mismos dos ejemplos que fueron implementados con las funciones
printf y scanf en la seccin anterior. El primero de ellos es bastante similar a su
contraparte con funciones de alto nivel, y esto se debe a que el mismo solo lee e
imprime cadenas y no otro tipo de datos. Sin embargo, note que debido a la
ausencia de un mecanismo como el proporcionado por el especificador de
formato %s, es necesario mostrar el resultado final con dos llamadas al
sistema independientes.
Programa en ensamblador:
.section .rodata
cad1:
.asciz "Por favor introduzca una cadena: "
cad2:
.asciz "La cadena introducida es: "
fcad2:
.section .bss
cadena: .space 50
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando que se escriba una cadena
movl $4, %eax
# Servicio #4 (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad1, %ecx
# Apuntador a la cadena a imprimir
movl $cad2-cad1, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (servicio de lectura)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Muestra el resultado (parte 1)
movl $4, %eax
# Servicio #4 (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
90
leal cad2, %ecx
movl $fcad2-cad2, %edx
int $0x80
#
#
#
#
Reserva
Reserva
Reserva
Reserva
espacio
espacio
espacio
espacio
para
para
para
para
un
un
un
la
entero
entero
entero
cadena introducida
.section .text
.globl _start
_start:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
91
# Muestra un mensaje solicitando que proporcione el valor de A
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad1, %ecx
# Apuntador a la cadena a imprimir
movl $cad2-cad1, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (read)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Obtiene el valor entero representado por la cadena
xorl %ecx, %ecx
# i=0
xorl %eax, %eax
# A=0
movl $10, %esi
# base decimal
for1:
movb cadena(%ecx), %bl # Carga un caracter. (cadena[i])
cmpb $0, %bl
# Si llega al final de la cadena
je ffor1
# Sale del ciclo
cmpb $10, %bl
# Si llega al final de la cadena
je ffor1
# Sale del ciclo
subb $'0', %bl
# Obtiene el dgito entero que representa
movzx %bl, %ebx
# Expande el entero a 32 bits (D)
mull %esi
# A=A*10
addl %ebx, %eax
# A=A+D
incl %ecx
# Se repite para el siguiente caracter
jmp for1
ffor1:
movl %eax, A
# Guarda el valor de A
# Muestra un mensaje solicitando que proporcione el valor de B
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad2, %ecx
# Apuntador a la cadena a imprimir
movl $cad3-cad2, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (read)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
92
# Obtiene el valor entero representado por la cadena
xorl %ecx, %ecx
# i=0
xorl %eax, %eax
# B=0
movl $10, %esi
# base decimal
for2:
movb cadena(%ecx), %bl
cmpb $0, %bl
je ffor2
cmpb $10, %bl
je ffor2
subb $'0', %bl
movzx %bl, %ebx
mull %esi
addl %ebx, %eax
incl %ecx
jmp for2
ffor2:
movl %eax, B
#
#
#
#
#
#
#
#
#
#
# Guarda el valor de B
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
93
# Muestra el resultado (parte 2)
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
addl %esi, %ecx
# Ajustamos la direccin de la cadena
movl $10, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
El subsistema de E/S
El subsistema de E/S de una computadora proporciona un modo de
comunicacin entre el sistema central y el ambiente externo. Los dispositivos de
E/S conectados a la computadora tambin se llaman perifricos. Un subsistema
de E/S consiste en interfases de E/S y dispositivos perifricos. La estructura
general de un susbsistema de E/S es la siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
94
CPU
MEMORIA
Bus de datos
Bus de direcciones
Bus de control
Interfaz de E/S
Subsistema de E/S
Dispositivo de E/S
Interfaz de E/S:
La interfaz de E/S proporciona un mtodo para transferir informacin entre
dispositivos de almacenamiento interno y dispositivos externos. El propsito del
enlace de comunicacin provisto por la interfaz es resolver las diferencias que
existen entre la computadora central y cada perifrico. Estas diferencias son:
Los cdigos de datos y los formatos en los perifricos son diferentes del
formato de palabra del sistema central.
implica
intercambiar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
rdenes,
95
papel atascado en una impresora. Tambin errores en la informacin
almacenada o transmitida, lo cual se logra por ejemplo mediante el uso
de un bit de paridad.
Programada
Basada en interrupciones
Entrada/Salida programada:
En este caso los datos se intercambian entre la CPU y la interfaz de E/S. La CPU
ejecuta un programa que le da el control directo de la operacin de entrada o
salida, donde se incluye la deteccin del estado del dispositivo, el envo de un
comando de lectura o escritura y la transferencia de datos.
Transferir datos bajo el control del programa requiere que la CPU realice un
monitoreo constante de perifricos. Cuando la CPU enva una orden a la interfaz
de E/S, debe esperar hasta que la operacin concluya. Una vez que se inicia una
transferencia de datos, es necesario que la CPU monitoree la interfaz para
detectar cuando puede volverse a realizar una transferencia, ya que la interfaz
no realiza ninguna accin para notificar a la CPU.
Este proceso toma mucho tiempo y mantiene ocupado el procesador mientras
espera por la disponibilidad del dispositivo. Adems, si la CPU es ms rpida
que la interfaz de E/S ste es un tiempo que la CPU desperdicia. Si bien es un
mtodo sumamente ineficiente, tiene la ventaja de ser el que requiriere la menor
cantidad de hardware para ser implementado.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
96
Entrada/Salida basada en interrupciones:
Esta tcnica permite que la CPU emita un comando de E/S hacia una interfaz y
luego ejecute otro trabajo. La interfaz se encargar de producir una interrupcin
para solicitar atencin de la CPU cuando est lista para intercambiar datos.
Cuando la CPU detecta la seal de interrupcin detiene la tarea que est
procesando, transfiere el control a una rutina de servicio (conocido como
manejador de interrupcin) para procesar la transferencia de entrada o salida y
luego regresa a la tarea que ejecutaba originalmente.
Tanto en la E/S programada como en la de interrupciones, la CPU es la
responsable de extraer los datos de la memoria principal en una salida y de
almacenar los datos en la memoria principal en una entrada. Si bien esta tcnica
es ms eficiente que la E/S programada, ya que permite que el CPU atienda
otras tareas mientras se espera por el dispositivo perifrico, la misma requiere
de la existencia de un mecanismo de interrupciones lo que incrementa los
requerimientos de hardware.
2.
3.
4.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
97
Esta tcnica es sumamente efectiva cuando se transmiten bloques de datos.
Aunque a simple vista pueda no parecerlo, el mecanismo de robo de ciclos es
sumamente efectivo, ya quelos dispositivos son muy lentos en comparacin a la
CPU. Por esta razn, cuando se produce un conflicto entre el dispositivo y la
CPU se le da prioridad al dispositivo.
Rango de puertos
Teclado
0x60 0x6F
0x1F0 0x1F7
Puerto de juegos
0x200 0x207
0x378 0x37F
0x3F8 0x3FF
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
98
Instrucciones in y out
La arquitectura IA-32 proporciona dos instrucciones que permiten enviar o
recibir datos hacia o desde un dispositivo perifrico utilizando E/S aislada.
Ambas instrucciones permiten la utilizacin de sufijos para indicar la longitud
de los datos a transferir. Cuando se utiliza la instruccin in, el destino debe ser
siempre el registro al, ax, o eax, dependiendo del tamao de los datos a recibir
desde el dispositivo. De forma similar, en el caso de la instruccin out, el origen
debe ser el registro al, ax o eax, dependiendo del tamao de los datos a enviar
al dispositivo.
El nmero de puerto (el origen en caso de una instruccin in, o el destino en el
caso de una instruccin out) puede especificarse como un inmediato si el mismo
puede ser representado en ocho bits. Por ejemplo, las siguientes instrucciones
permiten leer o escribir un byte desde o hacia el puerto 0x60:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
99
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
100
A continuacin se muestran todos los formatos vlidos para las instrucciones de
E/S aislada de la arquitectura IA-32:
Instruccin
inb Puerto, %al
inw Puerto, %ax
inl Puerto, %eax
Inmediato (8 bits)
registro dx
Efecto
%al Puerto
%axl Puerto
%eax Puerto
Operandos vlidos
registro al
registro al
Descripcin
mueve 1 byte
mueve 2 bytes
mueve 4 bytes
Ejemplo
inb $0x60, %al
inl %bx, %eax
Instruccin
outb %al, Puerto
Puerto%al
mueve 1 byte
Puerto%ax
mueve 2 bytes
Puerto%eax
mueve 4 bytes
registro al
registro al
Instruccin
insb
Efecto
edi edi 1
MEM[es:edi] Puerto
edi edi 2
MEM[es:edi] Puerto
edi edi 4
insl
Instruccin
outsb
outsl
Operandos vlidos
Inmediato (8 bits)
registro dx
MEM[es:edi] Puerto
insw
outsw
Efecto
Efecto
Puerto MEM[ds:esi]
esi esi 1
Puerto MEM[ds:esi]
esi esi 2
Puerto MEM[ds:esi]
esi esi 4
Descripcin
Ejemplo
outb %al, $0x60
outw %ax, %bx
Descripcin
mueve 1 byte desde el puerto indicado por el registro
bx
mueve 2 bytes desde el puerto indicado por el registro
bx
mueve 4 bytes desde el puerto indicado por el registro
bx
Descripcin
mueve 1 byte al puerto indicado por el registro bx
mueve 2 bytes al puerto indicado por el registro bx
mueve 4 bytes al puerto indicado por el registro bx
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
101
Dispositivos de E/S: El teclado
Anteriormente en este captulo introdujo el concepto de interfaz de E/S. El
propsito de la misma es permitir que la CPU controle una amplia variedad de
dispositivos con caractersticas distintas, de una forma relativamente
estandarizada. A continuacin se explota el diagrama de conexin de la interfaz
de E/S presentado anteriormente, con el fin de describir el diagrama de bloques
bsico de una interfaz de E/S:
El registro de datos acta como buffer para los datos intercambiados entre el
dispositivo y la CPU. Dicho registro puede ser escrito o ledo por la misma, de
acuerdo al tipo de operacin que se est realizando. Por ejemplo, en el caso de
un teclado, cada vez que se presiona una tecla, el cdigo que identifica a la
misma es colocado en este registro, para ser ledo posteriormente por la CPU.
En el caso de un puerto serial, este registro puede ser escrito por la CPU para
enviar datos al dispositivo conectado a dicho puerto.
El registro de estado refleja el estado actual del dispositivo manejado a tras de
la interfaz. Por ejemplo, en el caso de un mdem, dicho registro permite
determinar cuando el dispositivo est listo para transmitir datos, o cuando se ha
recibido uno desde el otro extremo de la lnea.
Por ltimo, el registro de control permite configurar la diferentes caractersticas
de funcionamiento del dispositivo controlado. Por ejemplo, al conectarse a un
router a travs de un puerto serial, es necesario configurar la interfaz para que
funcione a una velocidad de transmisin determinada. Dado que sobre el
registro de control solo se realizan operaciones de escritura, y sobre el registro
de estado solo se realizan operaciones de lectura, los mismos comparten el
mismo nmero de puerto sin que se exista ningn tipo de ambigedad.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
102
El teclado es el dispositivo de entrada ms utilizado en una computadora
moderna. Su registro de datos est identificado por el puerto 0x60, mientras
que el puerto 0x64 se utiliza para identificar al registro de estado (en una
lectura) o al registro de control (en una escritura).
Los datos proporcionados por el mismo son transmitidos a la computadora en
forma de cdigos de rastreo (scancodes). Los mismos no son otra cosa que un
nmero que identifica cada una de las diferentes teclas y sus estados. Los
mismos son producidos cuando el usuario presiona (o levanta) una (o varias)
teclas.
Cada modelo de teclado utiliza un cdigo interno (definido en el firmware), el
cual es traducido a la forma de un cdigo de rastreo al ser transmitido a la
computadora, con la intencin de estandarizar el uso de estos dispositivos. An
as, existen diferentes conjuntos de cdigos de rastreo. La mayora de los
teclados permiten seleccionar cual de dichos conjuntos se desea utilizar.
Para efectos de los ejemplos que sern presentados en la siguiente seccin, tan
solo es necesario comprender que el dispositivo identifica las diferentes teclas
mediante cdigos de rastreo, los cuales deben ser convertidos de alguna forma,
generalmente utilizando una tabla de conversin (conocida como keymap) para
obtener el caracter ASCII correspondiente.
Por lo general los cdigos de rastreo son asignados en base a la posicin que
ocupa cada tecla, comenzando de arriba a abajo y de izquierda a derecha.
Algunas excepciones a esta regla se hacen para mantener la compatibilidad con
modelos ms antiguos, en los que algunas teclas han sido aadidas y/o
eliminadas.
A continuacin se presentan los cdigos de rastreo que sern utilizados en los
ejemplos de la siguiente seccin. Los mismos pertenecen al conjunto de cdigos
#1. Si bien el conjunto de cdigos #2 es el ms utilizado actualmente, el mismo
es convertido al conjunto de cdigos #1 por un microprocesador en la tarjeta
madre de la computadora (esto es debido a razones histricas). Se recomienda
consultar bibliografa especializada para obtener informacin ms detallada al
respecto.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
103
Tecla
1
2
3
4
5
6
7
8
9
0
Q
W
E
R
T
Y
U
I
O
P
A
S
D
F
G
H
J
K
L
Z
X
C
V
B
N
M
ENTER
0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0A
0x0B
0x10
0x11
0x12
0x13
0x14
0x15
0x16
0x17
0x18
0x19
0x1E
0x1F
0x20
0x21
0x22
0x23
0x24
0x25
0x26
0x2C
0x2D
0x2E
0x2F
0x30
0x31
0x32
0x1C
0x82
0x83
0x84
0x85
0x86
0x87
0x88
0x89
0x8A
0x8B
0x90
0x91
0x92
0x93
0x94
0x95
0x96
0x97
0x98
0x99
0x9E
0x9F
0xA0
0xA1
0xA2
0xA3
0xA4
0xA5
0xA6
0xAC
0xAD
0xAE
0xAF
0xB0
0xB1
0xB2
0x9C
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
104
tabla de traduccin utilizada actualmente por su computadora, utilizando el
comando dumpkeys en la consola de comandos de Linux.
Ahora bien, cuando el usuario presiona (o levanta) una tecla, el cdigo de
rastreo correspondiente es colocado en el registro de datos del teclado.
Adicionalmente se enciende el bit 0 del registro de estado, para indicar que un
cdigo de rastreo vlido se encuentra en el registro de datos.
Un programa que utilice la tcnica de transferencia de E/S programada, deber
monitorear continuamente el estado de dicho bit para detectar que una tecla ha
sido presionada o levantada (en las otras tcnicas el teclado activa una
interrupcin con el fin de notificar este hecho).
De esta forma, el esqueleto bsico de un programa que desea recibir el cdigo
de rastreo de una tecla que ha sido presionada o levantada es el siguiente:
espera: inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
inb $0x60,%al
CMD, %al
%al,$0x60
DATA, %al
%al,$0x60
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
105
Ejemplos prcticos:
En esta seccin se presentan algunos ejemplos prcticos de utilizacin de las
instrucciones in y out. Al estudiar los mismos, debe tener en cuenta que al
interactuar en lenguaje de mquina con un dispositivo de E/S se estn rozando
los lmites que separan el software del hardware, por lo cual todo comienza a
ser mucho ms dependiente de este ltimo. En otras palabras: en este nivel, el
programa es 100% dependiente del hardware con el cual se est interactuando.
En este caso se utilizar un dispositivo sencillo y al alcance de todos: el teclado.
Se utilizar direccionamiento mediante E/S aislada utilizando las instrucciones
iny out. Adems en todos los ejemplos se utilizar la tcnica de E/S
programada, ya que el uso de cualquier otra tcnica involucrara modificar el
Sistema Operativo (por ejemplo para reemplazar el manejador de interrupciones
del teclado), tarea que se encuentra fuera del alcance de este libro.
Antes de ejecutar cualquiera de estos ejemplos es necesario tener en cuenta los
siguientes puntos:
An cuando el programa est interactuando con el teclado mediante E/S
programada, el manejador de interrupciones del teclado del Sistema
Operativo se mantiene activo, por lo cual el mismo captura y enva a la
consola de comandos cada una de las teclas presionadas.
Los puertos del teclado aqu utilizados son compartidos tambin por el
ratn. El ejecutar estos programas con el mismo conectado a la PC puede
causar conflictos y derivar en un comportamiento inesperado, en especial
en el ltimo ejemplo en el que se envan comandos al teclado.
Al estar utilizando E/S programada es posible que se pierdan algunas de
las teclas presionadas. La utilizacin de una computadora con un CPU
sumamente rpido ayuda a mejorar este aspecto, ms nunca puede
corregirlo del todo. Esto se nota en especial en el ltimo ejemplo, en el
que se debe esperar por un el teclado no solo para recibir datos sino
tambin para enviar comandos.
Dado que el programa solicita permiso para acceder directamente a los
puertos del teclado, el mismo no puede ser ejecutado sin permisos de
superusuario.
Con la intencin de minimizar los efectos causados por los problemas
anteriormente mencionados, se proponen las siguientes acciones:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
106
antes de encender la computadora para evitar cualquier tipo de conflicto
con dicho dispositivo.
Dicho todo esto, se recomienda seguir los siguientes pasos a la hora de ejecutar
los programas de ejemplo. En caso de no seguir dichos pasos el
comportamiento de los programas puede no ser el esperado:
Desconecte el ratn de la computadora antes de encender la misma.
Inicie la computadora.
Si la misma se inicia en modo grfico, presione las teclas CTRL+ALT+F1
para cambiar al primer terminal virtual.
Inicie sesin como superusuario en dicho terminal.
Cambie la frecuencia de reconocimiento y el retardo de repeticin del
teclado mediante el comando: kbdrate -r 2.0 -d 1000.
Compile y ejecute los programas de ejemplo.
Termine la sesin en el terminal virtual mediante el comando exit.
De ser necesario, regrese al entorno grfico presionando las teclas
CTRL+ALT+F7.
Apague la computadora.
Conecte de nuevo el ratn.
En este primer ejemplo, simplemente se muestra al usuario el scancode recibido
(en formato hexadecimal) cada vez que se presiona (o se levanta) una tecla. El
programa finaliza cuando se detecta el scancode 0x1C, correspondiente a la
tecla ENTER presionada:
.section .data
CAD:
.asciz "\bScancode leido: 0x%2x\n"
ERROR: .asciz "Se ha denegado el permiso sobre los puertos del
teclado\n"
SC:
.bss
.space 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
107
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
%eax,%eax
jne err
# No se obtuvo el permiso
# Limpia eax
# Lee el scancode del registro de datos
# Salvaguarda el scancode leido
pushl %eax
pushl $CAD
call printf
addl $8, %esp
cmpb $0x1C,SC
je fin
jmp espera
err:
pushl $ERROR
call printf
addl $4, %esp
fin:
#
#
#
#
#
# Termina el programa
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
108
Observe que el corazn del programa est compuesto de dos ciclos anidados:
en el ms interno se lee el registro de estado del teclado (puerto 0x64), y si
verifica si el bit 0 se encuentra encendido. Mientras esto no sea as, el programa
se mantiene esperando. Una vez que el usuario presiona una tecla, y el bit 0 del
registro de estado se enciende, el programa lee el cdigo de rastreo
almacenado en el registro de datos del teclado (puerto 0x60) e imprime el
mismo en formato hexadecimal mediante una llamada a printf.
Si dicho cdigo de rastreo coincide con el generado al presionar la tecla ENTER
(0x1C), el programa sale del ciclo externo y finaliza su ejecucin. Observe
adems que para poder acceder a los puertos mencionados, el programa solicita
permiso al sistema operativo mediante una llamada al servicio ioperm. De
manera similar los permisos son liberados al finalizar la ejecucin del programa.
Si se observa con detenimiento la salida de este programa, se verifica que tal y
como se describi anteriormente, el presionar y levantar una tecla genera dos
cdigos de rastreo exactamente iguales, con la diferencia de que el primero de
ellos tiene el bit 7 apagado, mientras que el segundo lo tiene encendido.
El siguiente programa es una versin modificada del anterior, en el cual en lugar
de mostrar el cdigo de rastreo recibido, se indica al usuario si la tecla
(cualquiera que esta sea) ha sido presionada o levantada. Nuevamente, el
programa finaliza una vez que el usuario presiona la tecla ENTER:
.section .data
CAD1:
.asciz "\bTecla presionada\n"
CAD2:
.asciz "\bTecla levantada\n"
ERROR: .asciz "Se ha denegado el permiso sobre los puertos del
teclado\n"
SC:
.bss
.space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
%eax,%eax
jne err
# No se obtuvo el permiso
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
109
espera: inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
# Limpia eax
# Lee el scancode del registro de datos
# Salvaguarda el scancode leido
si:
pushl SC
pushl $CAD1
call printf
addl $8, %esp
jmp fsi
sino:
pushl SC
pushl $CAD2
call printf
addl $8, %esp
fsi:
cmpb $0x1C,SC
je fin
jmp espera
err:
pushl $ERROR
call printf
addl $4, %esp
fin:
#
#
#
#
#
# Termina el programa
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
110
rastreo no tienen una correspondencia directa con el cdigo ASCII, no existe una
forma sencilla de convertir el cdigo de rastreo al ASCII que le corresponde para
poder imprimirlo mediante la funcin printf.
Una instruccin sumamente poderosa que se utiliza generalmente en este tipo
de programas es la instruccin xlat. Como su nombre lo indica, la misma sirve
para llevar a cabo una traduccin. En realidad lo que la misma realiza es una
bsqueda dentro de una tabla. La instruccin no recibe parmetros de forma
explcita, sino que asigna al registro %al, el byte ubicado en la posicin N de la
tabla, donde N es el valor que contena dicho registro antes de la ejecucin de la
instruccin xlat. La tabla se ubica en memoria, y su direccin de inicio debe
estar contenida en el registro ebx.
Por ejemplo, suponga que se desea traducir un dgito decimal a su cdigo ASCII
correspondiente. Esto es posible mediante el uso de una tabla de traduccin:
TABLA:
.ascii 0123456789
y la instruccin xlat:
movb NUM, %al
leal TABLA, %ebx
xlat
# %al = MEM[%ebx+%al]
.asciz "QWERTYUIOP****ASDFGHJKL*****ZXCVBNM"
SC:
.bss
.space 1
.section .text
.globl _start
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
111
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
%eax,%eax
jne err
espera: inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
xorl %eax, %eax
inb $0x60,%al
cmpb $0x1C,%al
je fin
# No se obtuvo el permiso
# Limpia eax
# Lee el scancode del registro de datos
# Si es ENTER (presionada) terminar
movb %al, SC
andb $0x80, %al
jne espera
cmpb $0x10, SC
jl noletra
cmpb $0x32, SC
jg noletra
#
#
#
#
pushl %eax
pushl $CAD
call printf
addl $8, %esp
jmp espera
Si
No
Si
No
el
es
el
es
scancode es menor al de la Q
una letra
scancode es mayor al de la M
una letra
noletra:
mostrar:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
112
err:
pushl $ERROR
call printf
addl $4, %esp
fin:
#
#
#
#
#
# Termina el programa
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
113
SC:
.section .bss
.space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
%eax,%eax
jne err
cero:
# No se obtuvo el permiso
movb %al, SC
andb $0x80, %al
jne espera
cmpb $0x0B, SC
je cero
# Si el scancode es el del 0
# Salta a cero
cmpb $0x02, SC
jl espera
cmpb $0x08, SC
jg espera
#
#
#
#
decb SC
jmp mostrar
# Resta 1 al scancode
movb $0, SC
# El dgito es 0
Si
No
Si
No
el
es
el
es
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
114
mostrar:
inb $0x64, %al
andb $2, %al
jne mostrar
#
#
#
#
#
#
err:
pushl $ERROR
call printf
addl $4, %esp
fin:
#
#
#
#
#
# Termina el programa
En este ejemplo se utilizan las mismas tcnicas que en el ejemplo anterior para
esperar que una tecla sea presionada y asegurarse que sea uno de los dgitos
del 0 al 7 en el teclado bsico. Luego el mismo es traducido a un patrn de
bits que representa los estados de los tres LEDs del teclado (1 encendido, 0
apagado). La idea de dicho patrn consiste en que los LEDs representen el
equivalente binario del dgito octal presionado por el usuario. La tabla fue
construida de la siguiente forma:
Octal
Binario
0
1
2
3
4
5
6
7
000
001
010
011
100
101
110
111
CAPS
0
0
1
1
0
0
1
1
SCROLL
0
1
0
1
0
1
0
1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
115
El patrn que se enva al teclado debe indicar el estado de cada uno de los tres
LED's en el orden CAPS-NUM-SCROLL. Sin embargo, la disposicin fsica de los
mismos en el teclado es NUM-CAPS-SCROLL. De all que en la tabla los bits 1 y
2 se encuentren invertidos con respecto al nmero binario.
Una vez obtenido el patrn a enviar, el programa debe esperar nuevamente por
el teclado, sin embargo en este caso no se espera a que se presione o levante
una tecla, sino a que el dispositivo est listo para recibir un comando. En este
caso, el bit del registro de estado utilizado para reflejar esta condicin es el bit
2 (en lugar del 0). Una vez que el teclado est dispuesto a recibir un comando,
se enva el mismo (0xED, utilizado para modificar el estado de los LEDs) seguido
del patrn anteriormente obtenido utilizando la instruccin outb dos veces.
Si bien los protocolos, registros y puertos varan de un dispositivo a otro, los
principios de funcionamiento ilustrados en estos cuatro ejemplos son los
mismos para cualquiera de ellos. Vale la pena comentar que en el lenguaje de
programacin C existen macros equivalentes a las instrucciones in y out, as
como una funcin equivalente a la llamada al sistema ioperm. Los manejadores
de interrupciones, por ejemplo, suelen ser escritos en lenguaje C y utilizar las
macros y funciones anteriormente mencionadas.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
116
Ejercicios
6.1- Escriba un programa que lea seis valores y los muestre por pantalla segn
el formato escogido por el usuario. Los formatos disponibles son:
[1] En una lnea horizontal en el orden de entrada
[2] En una lnea horizontal en orden inverso a la entrada
[3] De manera vertical en el orden de entrada
[4] De manera vertical en orden inverso a la entrada
Utilice las funciones printf y scanf.
6.2- Escriba un programa que lea cuatro valores enteros y calcule su suma.
Debe mostrar el resultado por pantalla. Utilice las funciones printf y scanf.
6.3- Escriba un programa que lea cuatro valores enteros y calcule su promedio.
Debe mostrar el resultado por pantalla. Utilice las funciones printf y scanf.
6.4- Escriba un programa que lea dos valores enteros a y b y produzca como
salida un resultado segn las siguientes condiciones:
Si a=b: resultado=a
Si a>b: resultado=a-b
Si a<b: resultado=b-a
Utilice las funciones printf y scanf.
6.5- Escriba un programa que lea la cantidad de minutos de duracin de una
llamada telefnica y que calcule el monto a pagar por dicha llamada de acuerdo
a la siguiente tarifa:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
117
6.10- Escriba un programa que permita emular el concepto de la cadena de
formato de la funcin scanf utilizando nicamente llamadas al sistema. Asuma
que la cadena de formato se encuentra en el segmento de datos en una etiqueta
llamada format. De igual forma asuma que la direccin de cada uno de los
argumentos adicionales se encuentran en un arreglo llamado params, en el
que cada elemento es una direccin de memoria de 4 bytes. Los especificadores
de formato vlido son nicamente %c y %s.
6.11- Escriba un programa que notifique al usuario cuando una de las teclas de
funcin (F1-F12) sea presionada o levantada. Utilice E/S programada.
6.12- Modifique el programa anterior, de manera que omita las repeticiones
generadas al mantener presionada durante cierto tiempo la tecla en cuestin.
6.13- Escriba un programa que notifique al usuario cuando se detecte que se ha
presionado la combinacin de teclas CTRL+ALT+Q. Utilice E/S programada
6.14- Escriba un programa que convierta el teclado en una calculadora binaria
de 3 bits. Para ello deber reconocer comandos de la forma [+*][XXX], donde OP
es una de las teclas '+' o '-', y X es una de las teclas '0' o '1'. El mismo deber
calcular la operacin especificada (+: OR a nivel de bit, *: AND a nivel de bit)
entre el acumulador (inicializado en cero) y el nmero binario introducido. El
resultado debe ser mostrado utilizando los LEDs del teclado. El programa
finaliza al presionar la tecla ENTER.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
118
es
posible
programar
directamente
en
lenguaje
ensamblador,
movl x, %ebx
movl y, %eax
cmpl %eax, %ebx
jg mayor
subl %ebx, %eax
movl %eax, result
jmp fin
subl %eax, %ebx
movl %ebx, result
#
#
#
#
#
#
#
#
#
%ebx = x
%eax = y
compara %ebx con %eax
si x>y salta a mayor
sino %eax=y-x
guarda el resultado
salta a fin
%ebx=x-y
guarda el resultado
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
119
El siguiente ejemplo es equivalente al anterior:
1
movl x, %ebx
2
movl y, %eax
3
cmpl %eax, %ebx
4
jle menorig
5
subl %eax, %ebx
6
movl %ebx, result
7
jmp fin
8 menorig: subl %ebx, %eax
9
movl %ebx, result
10 fin:
#
#
#
#
#
#
#
#
#
%ebx = x
%eax = y
compara %ebx con %eax
si x<=y salta a menorig
sino %ebx=x-y
guarda el resultado
salta a fin
%eax=y-x
guarda el resultado
#
#
#
#
#
valor de x
etiqueta "mayor"
etiqueta "menor"
mensaje 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
120
mayor:
pushl $mensaje2
call printf
jmp fin
pushl $mensaje3
call printf
movl $1, %eax
xorl %ebx, %ebx
int $0x80
menor:
fin:
Ciclos
Los ciclos permiten ejecutar un conjunto de instrucciones varias veces hasta que
se cumpla una condicin. El chequeo de la condicin puede estar al inicio o al
final del ciclo, en caso de estar al final hay que tener en cuenta que la ejecucin
se va a efectuar al menos una vez.
A modo de ejemplo se presentan cuatro versiones de un programa que imprime
los nmeros del 1 al 10.
Do while
Este ciclo revisa la condicin al final.
#include <stdio.h>
int x=0;
main()
{
do
{
x++;
printf("%d ",x);
}
while(x<10);
printf("\n");
}
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
121
# Programa que muestra por pantalla los numeros del 1 al 10
# Traduccion del do while
.section .data
formato:
.asciz"%d "
salto:
.asciz"\n"
.section .text
.globl _start
_start:
movl $0, %ebx
do:
incl %ebx
pushl %ebx
pushl $formato
call printf
addl $8, %esp
cmpl $10, %ebx
jl do
pushl $salto
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
%ebx=0, contador
incrementa %ebx
pasa el valor como parametro
pasa el formato como parametro
muestra el valor por pantalla
limpia la pila de parametros
compara %ebx con 10
salta al inicio del ciclo si %ebx < 10
imprime salto de linea
# termina el programa
While
En este caso la condicin se revisa al inicio del ciclo.
#include <stdio.h>
int x=1;
main()
{
while(x<=10)
{
printf("%d ",x);
x++;
}
printf("\n");
}
# Programa que muestra por pantalla los numeros del 1 al 10
# Traduccion del while
.section .data
formato:
.asciz"%d "
salto:
.asciz"\n"
.section .text
.globl _start
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
122
_start:
while:
finwhile:
#
#
#
#
#
#
#
#
#
#
%ebx=1, contador
compara %ebx con 10
salta a finwhile si %ebx > 10
pasa el valor como parametro
pasa el formato como parametro
muestra el valor por pantalla
limpia la pila de parametros
incrementa %ebx
salta al inicio del ciclo
imprime salto de linea
# termina el programa
For
Esta estructura permite expresar en una sola lnea el estado inicial del contador,
la condicin y cmo se realiza la cuenta.
#include <stdio.h>
int x;
main()
{
for(x=1;x<=10;x++) printf("%d ",x);
printf("\n");
}
# Programa que muestra por pantalla los numeros del 1 al 10
# Traduccion del for
.section .data
formato:
.asciz"%d "
salto:
.asciz"\n"
.section .text
.globl _start
_start:
movl $1, %ebx
for:
cmpl $10, %ebx
jg finfor
pushl %ebx
pushl $formato
call printf
addl $8, %esp
incl %ebx
jmp for
#
#
#
#
#
#
#
#
#
%ebx=1, contador
compara %ebx con 10
si %ebx>10 salta a fin de ciclo
pasa el valor como parametro
pasa el formato como parametro
muestra el valor por pantalla
limpia la pila de parametros
incrementa %ebx
salta al inicio del ciclo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
123
finfor:
pushl $salto
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
# termina el programa
pushl %ecx
pushl %edi
pushl $formato
call printf
addl $8, %esp
popl %ecx
incl %edi
loop muestra
#
#
#
#
#
#
#
#
#
pushl $salto
call printf
En este caso hay que salvaguardar el valor de %ecx en la pila antes de la llamada
a la funcin printf y luego restaurar ese registro debido a que las llamadas a
funciones o procedimientos pueden modificar algunos registros, entre ellos
%ecx. Esto se explica en detalle en el captulo 9.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
124
Ejercicios
7.1- Escriba un programa que lea un entero y que imprima el mensaje "Hola"
tantas veces como el nmero de entrada. El mensaje debe aparecer en pantalla
llenando lneas horizontales.
7.2- Escriba un programa que lea un entero y que imprima el mensaje "Hola"
tantas veces como el nmero de entrada. El mensaje debe aparecer en pantalla
una sla vez por cada lnea horizontal.
7.3- Escriba un programa que calcule xy.
7.4- Escriba un programa que determine el monto a pagar a un trabajador
semanal segn la siguiente estructura de pagos:
El pago por hora de trabajo (sueldo bsico) puede ser:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
125
Captulo 8. Arreglos
Cuando se declara un arreglo en C se escribe una expresin con la siguiente
estructura: T A[N]
Tamao de un dato
1 byte
4 bytes
8 bytes
Direccin inicial
XA
XB
XC
Elemento i
XA + i
XB + 4i
XC + 8i
Declaracin de arreglos
En lenguaje ensamblador los arreglos se declaran como una variable con varios
valores, por ejemplo si se declara el arreglo a como:
.section .data
a: .long 25,48,32,87
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
126
En este otro ejemplo:
.section .data
arr: .byte 5,4,3,7
Cada elemento del arreglo ocupa 1 byte. El tamao total de este arreglo es de 4
bytes.
.section .text
.globl _start
_start:
# En ambas soluciones se coloca el valor de la primera posicin
# del arreglo (10) en %eax y el valor de la tercera posicin del
# arreglo (30) en %ecx; arr denota la direccin inicial del
# arreglo. La escala es 4 porque el tipo de dato (entero) ocupa
# 4 bytes de memoria.
# solucin 1
movl $0, %ebx
movl arr(, %ebx, 4), %eax
movl $2, %ebx
movl arr(, %ebx, 4),%ecx
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
127
# solucin 2
leal arr, %edx
movl $0, %ebx
movl (%edx, %ebx, 4), %eax
movl $2, %ebx
movl (%edx, %ebx, 4), %ecx
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
inicializa %eax en 0
inicializa el ndice
suma un nuevo valor
incrementa el ndice
compara i con 10
si i<10 salta a suma
actualiza result
fin del programa
.byte 'a','b','c','d','a','s','a','w','f','a'
.section .text
.globl _start
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
128
_start:
verif:
noa:
finverif:
pushl $mensaje
call printf
pushl $mensaj2
call printf
addl $8, %esp
# mensaje inicial
# acumulador de ocurrencias
# indice para el arreglo
pushl %eax
pushl $salida
call printf
# lee caracter
# compara con a
#
#
#
#
si = a incrementa el indice
y el acumulador
lee siguiente caracter
si dif a solo incrementa indice
.section .text
.globl _start
_start:
leal arr, %ebx
# %ebx=dir inicial del arreglo
xorl %ecx, %ecx
# %ecx=0 indice
movl $1, %eax
# valor a guardar en el arreglo
genera:
cmpl $9, %ecx
# compara el indice con 9
jg fin
# salta a fin cuando indice=10
movl %eax, (%ebx, %ecx, 4)
# escribe valor en arr
incl %eax
# incrementa el valor
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
129
fin:
incl %ecx
movl $1, %eax
movl $0, %ebx
int $0x80
# incrementa el indice
# fin del programa
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
130
Ejercicios
8.1- Escriba un programa que lea un arreglo de n enteros y sume los elementos
del arreglo.
8.2- Escriba un programa que lea un arreglo de 20 enteros y calcule el
promedio de los nmeros del arreglo.
8.3- Escriba un programa que lea un arreglo de n enteros y calcule la cantidad
de nmeros pares.
8.4- Escriba un programa que lea un arreglo de n enteros y calcule la sumatoria
de los nmeros pares.
8.5- Escriba un programa que lea un arreglo de 12 enteros determine el mayor
e indique en que posicin se encuentra.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
131
Captulo 9. Procedimientos
Los procedimeintos son segmentos de programa sumamente tiles para evitar
la repeticin de cdigo, un programa con procedimientos es adems mucho
ms legible.
Una llamada a un procedimiento involucra el pase de informacin tanto hacia el
procedimiento como de retorno y el pase del control de flujo de ejecucin de
una parte del cdigo hacia otra. El pase de informacin desde y hacia el
procedimiento se realiza a travs de la pila. La porcin de la pila asignada a una
llamada a un procedimiento se conoce como marco de pila. Para utilizar la pila
se usan dos registros que sirven de apuntadores: %ebp es el apuntador de
marco de pila y %esp es el apuntador de pila, ste es el registro cuyo contenido
cambia mientras se ejecuta el procedimiento.
Descripcin
call etiqueta
llamada a procedimiento
leave
ret
retorno de procedimiento
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
132
popl %ebp
Procedimiento:
Prlogo:
Eplogo:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
133
Programa invocador:
El resultado (de existir) est en %eax y debe ser movido a otra localidad
# procedimiento:
# prlogo:
pushl %ebp
# se preserva marco de pila anterior
movl %esp, %ebp
# se actualiza marco de pila
pushl %ebx
# se preservan los registros del invocado
pushl %esi
pushl %edi
# cuerpo del programa
# aqui van las instrucciones del procedimiento
# eplogo:
movl resul, %eax # si hay un valor de retorno se guarda en %eax
popl %edi
# se restauran los registros
popl %esi
popl %ebx
leave
# se prepara la pila para el retorno
ret
# regresa el control al programa invocador
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
134
Pase de parmetros
Los parmetros a pasar hacia el procedimiento pueden ser de dos tipos: por
valor o por referencia. Cuando se pasa un parmetro por valor se genera una
copia del valor del parmetro y ese dato es el que est disponible en el
procedimiento, el procedimiento o funcin no puede cambiar el parmetro.
Cuando se pasa un parmetro por referencia realmente se pasa la direccin del
parmetro, no su valor, y al estar la direccin disponible durante la ejecucin
del procedimiento, el valor all guardado puede ser modificado.
Para pasar informacin acerca de un arreglo, se pasa la direccin inicial del
arreglo.
Ejemplo de programa con pase de parmetro por valor
El siguiente es un programa con una funcin que calcula el cuadrado de un
nmero entero. Paso de un parmetro por valor. Retorna el resultado como un
entero.
Programa en C:
#include <stdio.h>
int cuadrado(int x);
int t=10;
int s;
main()
{
s=cuadrado(t);
printf("cuadrado: %d\n", s);
}
int cuadrado(int x)
{
x=x*x;
return x;
}
Programa en ensamblador:
.section .data
t: .long 10
formato: .asciz "cuadrado: %d\n"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
135
.section .text
.globl _start
_start:
pushl t
call cuadrado
addl $4, %esp
pushl %eax
pushl $formato
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
cuadrado:
#
#
#
#
se apila el parmetro t
llamada al procedimiento
limpieza de la pila (4 bytes)
mostrar el resultado por pantalla
# termina el programa
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
imull %eax, %eax
leave
ret
#
#
#
#
Estado de la pila
Se denotan los cambios en las direcciones slo con un desplazamiento a partir
de la direccin inicial de %ebp.
Cuando se apila el parmetro y se realiza la llamada al procedimiento:
pushl t
call cuadrado
%esp
%esp
%ebp
-4
0
t
%ebp
-8
-4
0
dir retorno
t
En el procedimiento:
%esp -12
-8
-4
%ebp
0
pushl %ebp
%ebp = 0
dir retorno
t
%ebp=%esp -12
-8
-4
0
movl %esp,%ebp
%ebp = 0
dir retorno
t
popl %ebp
movl 8(%ebp),%eax
movl %ebp,%esp
%ebp=%esp -12
%ebp = 0
%esp=%ebp -12
%ebp = 0
-8 dir retorno
-8
dir retorno
-4
t
-4
t
0
0
popl %ebp
ret
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
136
-12
%esp -8
-4
%ebp 0
%ebp = 0
dir retorno
t
-12
-8
%esp -4
%ebp 0
%ebp = 0
dir retorno
t
%ebp +0
dir retorno
t
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
137
void duplica(int arr[4],int y)
{
int i;
int temp;
for(i=0;i<y;i++)
{
temp=arr[i]*2;
arr[i]=temp;
}
}
Programa en ensamblador:
.section
a: .long
n: .long
formato:
.data
10, 20, 30, 40
4
.asciz "%d\n"
.section .text
.globl _start
_start:
leal a, %eax
pushl %eax
pushl n
call duplica
addl $8, %esp
xorl %ebx, %ebx
xorl %edi, %edi
ciclo: movl a(,%ecx,4), %ebx
pushl %ebx
pushl $formato
call printf
incl %edi
cmpl n, %edi
jl ciclo
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
# imprime el nmero
duplica:
for:
pushl %ebp
#
movl %esp, %ebp
#
movl 8(%ebp), %esi
#
movl 12(%ebp), %edx
#
xorl %ecx, %ecx
#
movl (%edx,%ecx,4), %eax
addl %eax, %eax
#
movl %eax, (%edx,%ecx,4)
incl %ecx
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
138
cmpl %esi, %ecx
jl for
leave
ret
#
#
#
#
El siguiente programa tiene una funcin que calcula la suma de los elementos
de un arreglo de enteros de 10 posiciones. Se leen los datos del arreglo y se
muestra por pantalla el resultado. Paso de parmetro por referencia. La funcin
suma retorna un valor entero.
#include <stdio.h>
int suma(int arreglo[10]);
void leer(int arreglo[10]);
main()
{
int a[10];
int resultado;
leer(a);
resultado=suma(a);
printf("El resultado de sumar los elementos del arreglo es: %d\n", resultado);
}
void leer(int arreglo[10])
{
int x,i;
printf("Introduzca 10 enteros:\n");
for(i=0;i<10;i++)
{
scanf("%d",&x);
arreglo[i]=x;
}
}
int suma(int arreglo[10])
{
int i;
int res=0;
for(i=0;i<10;i++)
res=res+arreglo[i];
return res;
}
# Programa que lee un arreglo de enteros de 10 posiciones
# y suma los elementos del arreglo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
139
.section .data
leearr:
.asciz"Introduzca los 10 numeros del arreglo:\n"
dato:
.asciz"%d"
salida:
.asciz"La suma de los elementos del arreglo es: %d\n"
.section .bss
a:
.space 40
.section .text
.globl _start
_start:
pushl $leearr
call printf
leal dato, %edx
pushl %edx
leal a, %eax
pushl %eax
call leer
addl $8, %esp
leal a, %eax
pushl %eax
call suma
addl $4, %esp
pushl %eax
pushl $salida
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
leer:
leenum:
suma:
# imprime el resultado
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ebx
movl 12(%ebp), %esi
xorl %edi, %edi
pushl %ebx
pushl %esi
call scanf
addl $4,%ebx
incl %edi
cmpl $10,%edi
jl leenum
leave
ret
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ebx
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
140
sumar:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
141
finsum:
pushl %esi
pushl y
pushl x
pushl $salida
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
Este programa funciona bien, pero si cambiamos el registro %edi por %edx,
entonces el programa arroja un resultado invlido.
# Programa que calcula x multiplicado por y por sumas sucesivas
# Muestra el numero de iteracion cada vez que se realiza una suma
# y el subtotal de la suma
.section .data
x:
.long 25
y:
.long 4
iterac:
.asciz"Iteracion numero: %d, subtotal: %d\n"
salida:
.asciz"%d multiplicado por %d es: %d\n"
.section .text
.globl _start
_start:
movl x, %ebx
movl $1, %edx
movl $0, %esi
suma:
cmpl y, %edx
jg finsum
addl %ebx, %esi
pushl %esi
pushl %edx
pushl $iterac
call printf
incl %edx
jmp suma
finsum:
pushl %esi
pushl y
pushl x
pushl $salida
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
142
Esto se debe a que el contenido de %edx es modificado durante la ejecucin de
la funcin printf y ello afecta el funcionamiento del ciclo.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
143
Ejercicios
9.1- Escriba un programa que lea un arreglo de 20 enteros y calcule el
promedio de los nmeros pares del arreglo. Debe invocar un procedimiento que
indique cuntos nmeros son pares y calcule su suma.
9.2- Escriba un programa que lea un arreglo de n enteros y calcule la sumatoria
de los nmeros mayores que 10 y menores que 100 presentes en el arreglo.
9.3- Escriba un programa que dado un nmero de entrada "n", muestre por
pantalla el factorial de n (n!).
9.4- Escriba un programa que dado un nmero de entrada "n", siendo n mayor
que 2, muestre por pantalla la serie de Fibonacci de los primeros n nmeros. La
serie de Fibonacci se genera con la siguiente expresin:
Fn=Fn-1+Fn-2 con F1=F2=1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
144
Descripcin
Mueve un byte
Mueve 2 bytes
Mueve 4 bytes
Esto
se
puede
hacer
utilizando
la
instruccin
leal
Cada vez que se invoca la instruccin movs los registros %esi y %edi se
actualizan automticamente incrementndose o decrementndose el nmero de
bytes de la instruccin ejecutada. El incremento o decremento depende del valor
de la bandera DF ubicada en el registro EFLAGS. Si la bandera est en cero, los
registros sern incrementados, si est en uno, sern decrementados. Se puede
actualizar la bandera usando las instrucciones cld para colocar la bandera en 0
y std para colocarla en 1.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
145
El siguiente es un programa que mueve una cadena declarada en la seccin de
datos. El primer programa mueve una cadena de un caracter, el siguiente mueve
una cadena de cuatro caracteres.
# Programa que mueve una cadena de una posicion de memoria a otra
# Cadena de un caracter
.section .data
fuente:
.asciz"a"
salida:
.asciz"%s\n"
.section .bss
destino: .space 2
.section .text
.globl _start
_start:
leal fuente, %esi
leal destino, %edi
movsb
pushl $destino
pushl $salida
call printf
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
146
movl $1, %eax
movl $0, %ebx
int $0x80
El prefijo rep
Este prefijo se puede utilizar para repetir la ejecucin de una instruccin de
manejo de cadena de caracteres. Es controlado implcitamente por el registro
%ecx, repite la instruccin hasta que %ecx sea igual a 0.
Hay que actualizar el registro %ecx con la cantidad de movimientos de datos
que se van a realizar, por ejemplo si queremos mover una cadena de 8 bytes y
usamos la instruccin movsb entonces hay que colocar %ecx en 8, si usamos
movsw, %ecx debe estar en 4 y si usamos movsl entoces %ecx debe ser
actualizado en 2.
Ejemplo de un programa que usa el prefijo rep para mover una cadena un byte
a la vez, es decir, un caracter a la vez.
# Programa que mueve una cadena de una posicion de memoria a otra
.section .data
fuente:
.asciz"abcdefghijklmnopqrstuvwxyz"
salida:
.asciz"%s\n"
tamano:
.long 26
# numero de caracteres de la cadena
.section .bss
destino: .space 27
.section .text
.globl _start
_start:
leal fuente, %esi
leal destino, %edi
movl tamano, %ecx
rep movsb
pushl $destino
pushl $salida
call printf
#
#
#
#
%esi=dir de inicio
%edi=dir de inicio
%ecx se inicializa
mueve un byte a la
de la cadena fuente
de la cadena destino
en 26
vez durante 26 veces
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
147
Existen cuatro prefijos adicionales que adems de monitoriar el estado del
registro %ecx dependen del valor de la bandera de cero (ZF), estos son:
repe
repne
repnz
repz
repite
repite
repite
repite
mientras
mientras
mientras
mientras
igual
no igual
no cero
cero
(equivalente a repne)
(equivalente a repe)
La instruccin lods
La instruccin lods se utiliza para mover una cadena de caracteres desde
memoria hacia el registro %eax, usa el registro implcito %esi para indicar la
direccin de la cadena.
Instruccin
lodsb
lodsw
lodsl
Descripcin
Carga un byte en %al
Carga 2 bytes en %ax
Carga 4 bytes en %eax
La instruccin stos
La instruccin stos se usa para transferir una cadena que est en el registro
%eax a una posicin de memoria. Usa como operando destino implcito el
registro %edi.
Instruccin
stosb
stosw
stosl
Descripcin
Transfiere un byte de %al a memoria
Transfiere dos bytes de %ax a memoria
Transfiere cuato bytes de %eax a memoria
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
148
leal destino, %edi
movl tamano, %ecx
codif:
lodsb
subb $32, %al
stosb
loop codif
#
#
#
#
pushl $destino
pushl $salida
call printf
La instruccin cmps
La instruccin cmps se usa para comparar cadenas de caracteres, los operandos
estn implcitos en los registros %esi y %edi como en los casos anteriores. Esta
instruccin resta el valor de la cadena de destino del valor de la cadena fuente y
esta operacin modifica las banderas en EFLAGS.
Instruccin
cmpsb
cmpsw
cmpsl
Descripcin
Compara el valor de un byte
Compara el valor de 2 bytes
Compara el valor de 4 bytes
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
e indica
149
.globl _start
_start:
pushl $solicita1
call printf
pushl $cad1
pushl $formato
call scanf
pushl $salto
call printf
pushl $solicita2
call printf
pushl $cad2
pushl $formato
call scanf
leal cad1, %esi
cad1
cad2
movl $100, %ecx
rep cmpsb
jne noigual
pushl $iguales
call printf
jmp fin
pushl $diferent
call printf
noigual:
fin:
Luego
de
comparar
dos
cadenas
tambin
se
pueden
realizar
saltos
El peso depende del orden alfabtico. Las primeras letras del alfabeto
tienen mayor peso, es decir la "a" es mayor que la "b" que a su vez es
mayor que la "c" y as sucesivamente.
Por ejemplo la cadena "cola" es mayor que la cadena "hola" que a su vez es
mayor que "Hola".
Estas reglas siguen los valores de codificacin de caracteres del cdigo ASCII.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
150
Cuando se comparan cadenas de diferente tamao la situacin es ms
complicada, las reglas son las siguientes:
La instruccin scas
La instruccin scas permite buscar caracteres dentro de una cadena.
Instruccin
scasb
scasw
scasl
Descripcin
Compara un byte en memoria con el valor en %al
Compara dos bytes en memoria con el valorde %ax
Compara cuatro bytes en memoria con el valor de %eax
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
151
# Programa que busca un caracter en una cadena de caracteres
.section .data
mensaje1:
.asciz"Este programa solicita una cadena de caracteres y un
caracter\n"
mensaje2:
.asciz"a buscar dentro de la cadena, indica si el caracter
fue encontrado\n"
solict1:
.asciz"Introduzca la cadena de caracteres (maximo 100
caracteres): "
solict2:
.asciz"Introduzca el caracter a buscar: "
format1:
.asciz"%s"
format2:
.asciz"La cadena tiene %d caracteres\n"
noesta:
.asciz"El caracter %s no se encuentra en la cadena\n"
siesta:
.asciz"El caracter %s se encuentra en la cadena\n"
tam:
.long 0
.section .bss
cadena:
.space 100
caracter:
.space 1
.section .text
.globl _start
_start:
pushl $mensaje1
#
call printf
pushl $mensaje2
call printf
addl $8, %esp
pushl $solict1
#
call printf
addl $4, %esp
leal cadena, %edx
pushl %edx
pushl $format1
call scanf
#
addl $8, %esp
pushl $solict2
#
call printf
addl $4, %esp
leal caracter, %edx
pushl %edx
pushl $format1
call scanf
#
cld
leal cadena, %edi
movl $100, %ecx
movb $0, %al
repne scasb
mensaje inicial
lectura de la cadena
mensaje que solicita el caracter a buscar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
152
jne fin
subl$100, %ecx
neg %ecx
decl %ecx
movl %ecx, tam
pushl %ecx
pushl $format2
call printf
addl $8, %esp
#
#
#
#
#
#
pushl $caracter
pushl $siesta
call printf
jmp fin
pushl $caracter
pushl $noesta
call printf
nohay:
fin:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
153
Ejercicios
10.1.- Escriba un programa que realice la revisin de una contrasea, debe
inidicar si la contrasea introducida es correcta.
10.2.- Escriba un programa que detecte la presencia del caracter "-" en una
cadena de caracteres, el programa debe leer la cadena e indicar la posicin de la
primera aparicin del caracter.
10.3.- Escriba un programa que cuente el nmero de ocurrencias del caracter
"y" en una cadena.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
154
cada
parte de la
notacin, coeficiente y
exponente, se
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
155
disponibles, si se apila un noveno valor ste reemplaza el contenido de %st(0),
por ello se dice que la pila es circular.
La FPU tiene su propio registro de estado el cual indica las condiciones de
operacin de la unidad. Es un registro de 16 bits que contiene las banderas
siguientes:
Bit de estado
Descripcin
Falla de pila
10
11-13
14
15
Los seis primeros bits son banderas de excepcin se activan cuando ocurre una
excepcin durante el procesamiento de instrucciones en la FPU, se mantienen
activas hasta que un programa las desactive.
Este registro puede ser ledo transfiriendo su contenido a una doble palabra de
memoria o hacia el registro %ax. Esto se logra mediante el uso de la instruccin
fstsw.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
156
Asimismo la FPU provee un registro de control el cual controla su operacin. Sus
bits se especifican como:
Bit de control
Descripcin
6-7
Reservado
8-9
Control de precisin
10-11
Control de redondeo
12
Control de infinito
13-15
Reservado
Los primeros seis bits se usan para controlar qu banderas del registro de
estado son usadas, cuando uno de estos bits est activo impide que la bandera
correspondiente en el registro de estado pueda ser activada. Estos bits se
encuentran activos por defecto, enmascarando as todas las excepciones. Los
bits siguientes proveen la capacidad de escoger ciertas condiciones de
funcionamiento de la FPU.
Los bits 8 y 9 definen la precisin con la cual se trabaja, las opciones son las
siguientes:
00011011-
precisin simple
no se usa
precisin doble
precisin doble extendida
00011011-
Por defecto la FPU trabaja con precisin doble extendida y con redondeo hacia
el valor ms cercano. El valor del registro de control, por defecto, es: 0x037F.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
157
Redondeo
Precisin
bit
15
bit
14
bit
13
bit
12
bit
11
bit
10
bit
9
bit
8
bit
7
bit
6
bit
5
bit
4
bit
3
bit
2
bit
1
bit
0
Para modificar las condiciones hay que modificar el contenido del registro de
control. Esto se hace con la instruccin fldcw la cual carga una doble palabra en
el registro de control.
Ejemplo de un programa que cambia la precisin a simple, notse que es
necesario cambiar los bits 8 y 9 a la combinacin 00, por lo cual el nuevo valor
del registro de control debe ser: 0x007F.
.section .data
simple:
.byte 0x7F, 0x00
.section .text
.globl _start
_start:
fldcw simple
movl $1, %eax
movl $0, %ebx
int $0x80
Descripcin
Apila un valor de precisin simple (32 bits)
Apila un valor de precisin doble (64 bits)
flds valor1
fldl valor2
Ejemplo
valor1 declarado como .float
valor2 declarado como .double
Esta instruccin tiene varios formatos con valores predeterminados, ellos son
los siguientes:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
158
Instruccin
fld1
fldl2t
fldl2e
fldpi
fldlg2
fldln2
fldz
Descripcin
Apila +1.0
Apila log(base 2) 10
Apila log(base 2) e
Apila el valor de pi ()
Apila log(base10) 2
Apila log(base e) 2
Apila +0.0
Descripcin
Apila un valor entero de 32 bits
Apila un valor entero de 64 bits
Ejemplo
flds entero1
fldl entero2
Descripcin
Copia el dato del tope de la pila a otro registro FPU
fsts etiqueta
fstl etiqueta
Ejemplo
fst %st(4) copia el contenido de %st(0) y lo
guarda en %st(4)
fsts variable1 copia el contenido de %st(0) y lo
guarda en variable1 (32 bits)
fstl variable2 copia el contenido de %st(0) y lo
guarda en variable2 (64 bits)
Descripcin
Desapila el dato del tope de la pila y lo mueve a
otro registro FPU
Desapila el dato del tope de la pila y lo mueve a
memoria (32 bits)
Desapila el dato del tope de la pila y lo mueve a
memoria (64 bits)
Ejemplo
fstp %st(4) desapila contenido de %st(0) y
lo mueve a %st(4)
fstps variable1 desapila el contenido de
%st(0) y lo mueve a variable1 (32 bits)
fstpl variable2 desapila el contenido de
%st(0) y lo mueve a variable2 (64 bits)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
159
fist (lee nmero entero del tope de la pila)
Instruccin
fists etiqueta
fistl etiqueta
Descripcin
Desapila el valor presente en el tope de la pila y lo
guarda en memoria (32 bits)
Desapila el valor presente en el tope de la pila y lo
guarda en memoria (64 bits)
Ejemplo
fists valor1
fistl valor2
Descripcin
Intercambia el dato del tope de la pila
y otro registro de la pila
Ejemplo
fxch %st(1)
Instrucciones de control
finit (inicializacin)
Esta instruccin inicializa la FPU. No modifica los contenidos de los registros de
datos, coloca el registro de control en sus valores por defecto.
fstcw (copia el contenido del registro de control)
Con esta instruccin se crea una copia del contenido del registro de control en
una posicin de memoria.
fstsw (copia el contenido del registro de estado)
Con esta instruccin se crea una copia del contenido del registro de estado en
una posicin de memoria.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
160
Descripcin
Suma valor de 32 bits al tope de la pila
Suma valor de 64 bits al tope de la pila
Suma contenido de %st(x) con %st(0), guarda el
resultado en %st(0)
Suma %st(0) con %st(x), guarda el resultado en %st(x)
Suma %st(0) con %st(x), guarda el resultado en %st(x)
y desapila %st(0)
Suma %st(0) con %st(1), guarda el resultado en
%st(1), desapila %st(0)
Suma valor entero de 32 bits a %st(0), guarda el
resultado en %st(0)
Suma valor entero de 64 bits a %st(0), guarda el
resultado en %st(0)
Ejemplo
fadds valor1
faddl valor2
fadd %st(4), %st(0)
Descripcin
Resta tope de la pila menos valor de 32 bits
Resta tope de la pila menos valor de 64 bits
Resta el contenido de %st(x) menos %st(0), guarda el
resultado en %st(0)
Resta %st(0) menos %st(x), guarda el resultado en
%st(x)
Resta %st(0) menos %st(x), guarda el resultado en
%st(x) y desapila %st(0)
Resta %st(0) menos %st(1), guarda el resultado en
%st(1), desapila %st(0)
Resta %st(0) menos valor entero de 32 bits, guarda el
resultado en %st(0)
Resta %st(0) menos valor entero de 64 bits, guarda el
resultado en %st(0)
Ejemplo
fsubs valor1
fsubl valor2
fsub %st(4), %st(0)
fsub (resta)
Instruccin
fsubs etiqueta
fsubl etiqueta
fadd %st(x), %st(0)
fsub %st(0), %st(x)
fsubp %st(0), %st(x)
fsubp
fisubs etiqueta
fisubl etiqueta
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
161
fmul (multiplicacin)
Instruccin
fmuls etiqueta
fmull etiqueta
fmul %st(x), %st(0)
fmul %st(0), %st(x)
fmulp %st(0), %st(x)
fmulp
fimuls etiqueta
fimull etiqueta
Descripcin
Multiplica tope de la pila por valor de 32 bits
Multiplica tope de la pila por valor de 64 bits
Multiplica el contenido de %st(x) por %st(0), guarda el
resultado en %st(0)
Multiplica %st(0) por %st(x), guarda el resultado en
%st(x)
Multiplica %st(0) por %st(x), guarda el resultado en
%st(x) y desapila %st(0)
Multiplica %st(0) por %st(1), guarda el resultado en
%st(1), desapila %st(0)
Multiplica %st(0) por valor entero de 32 bits, guarda el
resultado en %st(0)
Multiplica %st(0) por valor entero de 64 bits, guarda el
resultado en %st(0)
Ejemplo
fmuls valor1
fmull valor2
fmul %st(4), %st(0)
Descripcin
Divide el tope de la pila entre valor de 32 bits
Divide el tope de la pila entre valor de 64 bits
Divide el contenido de %st(x) entre %st(0), guarda el
resultado en %st(0)
Divide %st(0) entre %st(x), guarda el resultado en
%st(x)
Divide %st(0) entre %st(x), guarda el resultado en
%st(x) y desapila %st(0)
Divide %st(0) entre %st(1), guarda el resultado en
%st(1), desapila %st(0)
Divide %st(0) entre valor entero de 32 bits, guarda el
resultado en %st(0)
Divide %st(0) entre valor entero de 64 bits, guarda el
resultado en %st(0)
Ejemplo
fdivs valor1
fdivl valor2
fdiv %st(4), %st(0)
fdiv (divisin)
Instruccin
fdivs etiqueta
fdivl etiqueta
divl %st(x), %st(0)
fdiv %st(0), %st(x)
fdivp %st(0), %st(x)
fdivp
fidivs etiqueta
fidivl etiqueta
Descripcin
calcula 2 elevado al contenido de %st(0) menos 1
calcula el valor absoluto de %st(0)
cambia el signo del valor en %st(0)
calcula el coseno del valor en %st(0) en radianes, guarda el resultado en %st(0)
calcula el resto de dividir el valor en %st(0) entre el valor en %st(1)
redondea el valor en %st(0) al entero ms cercano
calcula %st(0) elevado al valor en %st(1)
calcula el seno del valor en %st(0) en radianes, guarda el resultado en %st(0)
calcula la raiz cuadrada del valor en %st(0)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
162
La instruccin frndint redondea el valor en %st(0) al entero ms cercano usando
el mtodo de redondeo que se encuentre en el registro de control.
La instruccin fprem1 calcula el resto de la divisin de manera iterativa. Se
puede saber cuando la operacin culmina revisando el bit 2 del registro de
estado, cuando ese bit se encuentra en cero, las iteraciones estn completas.
Este proceso se debe realizar dentro de un ciclo, tal como se ejemplifica en el
siguiente programa:
.section .data
valor1:
.float 25.45
valor2:
.float 2.24
.section .bss
.space resultado, 4
.section .text
.globl _start
_start:
finit
flds valor2
flds valor1
ciclo:
fprem1
fstsw %ax
testb $4, %ah
jnz ciclo
fsts resultado
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
inicializacion de FPU
carga valor2
carga valor1
calcula resto de div valor1/valor2
copia registro de estado en %ax
chequea bit 2 del registro de estado
mientras diferente de 0 vuelva a ciclo
actualiza resultado con el resto
fin del programa
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
163
Instrucciones de comparacin
En los primeros modelos de mquinas Intel era necesario leer el registro de
estado y actualizar, por medio de un programa, el contenido del registro de
banderas (EFLAGS) para poder realizar saltos de acuerdo a las comparaciones
realizadas. A partir del procesador Pentium Pro se introduce un conjunto de
instrucciones que actualizan automticamente el registro de banderas. Estas son
las instrucciones presentadas a continuacin:
Instruccin
fcomi %st(x)
fcomip %st(x)
fucomi %st(0), %st(x)
fucomip %st(0), %st(x)
Descripcin
compara %st(0) con %st(x)
compara %st(0) con %st(x) y desapila
revisa si los valores en %st(0) y en %st(x) son vlidos
revisa si los valores en %st(0) y en %st(x) son vlidos y desapila
Ejemplo
fcomi %st(4)
fcomip %st(3)
fucomi %st(0), %st(2)
fucomip %st(0), %st(3)
ZF (Bandera de cero)
PF (Bandera de paridad)
CF (Bandera de acarreo)
%st(0)> %st(x)
%st(0)< %st(x)
%st(0) = %st(x)
# mensaje inicial
# inicializacion de FPU
# carga c en %st(0)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
164
fsubs d
flds a
fadds b
fmul %st(1), %st(0)
#
#
#
#
%st(0)=%st(0)-d
(c-d)
carga a en %st(0), %st(1)=c-d
%st(0)=%st(0)+b
(a+b)
%st(0)=%st(0)*%st(1)
#
#
#
#
Para mostrar el resultado por pantalla se puede usar la funcin printf pero hay
que tener en cuenta que el formato de salida debe ser %f para mostrar un
nmero fraccionario. Asimismo cuando se desapila el resultado se debe usar la
instruccin fstpl la cual desapila el valor de 8 bytes y lo coloca en memoria.
Para hacer esto primero se resta 8 al apuntador %esp (para reservar 8 bytes) y
luego con la instruccin fstpl (%esp) se "apila" el valor como parmetro para la
llamada a la funcin printf.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
165
Ejercicios
11.1- Escriba un programa que calcule la nota definitiva tomando en cuenta 6
notas con los siguientes porcentajes:
Nota 1: 20%
Nota 2: 15%
Nota 3: 25%
Nota 4: 10%
Nota 5: 25%
Nota 6: 5%
El programa debe mostrar la nota final con dos decimales y la nota definitiva
redondeada, el redondeo debe ser hacia arriba.
11.2.- Escriba un programa que permita convertir grados Centgrados a
Fahrenheit.
11.3.- Escriba un programa que acepte como entradas 10 valores de
temperatura en grados Centgrados y muestre su promedio.
11.4.- Escriba un programa que solicite el valor del dimetro de un crculo y
calcule su rea.
11.5.- Escriba un programa que permita realizar la conversin de kilmetros a
millas y de millas a kilmetros.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
166
dentro
de
un
entorno
grfico
para
modificar
este
archivo,
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
167
Apertura:
Lectura:
Escritura:
Cierre:
que
pueden
ser
realizadas
sobre
un
archivo,
las
cuales
no
Tipos de archivo
Un archivo puede ser clasificado de acuerdo a la forma en la que es almacenada
la informacin dentro del mismo. En este sentido, existen dos tipos de archivo:
archivos de texto y archivos binarios. Esta distincin es sumamente importante,
ya que es necesario conocer el tipo de archivo que se est manejando para
manipularlo adecuadamente.
Archivos de texto
Un archivo de texto es una secuencia de caracteres (generalmente imprimibles),
en el cual la informacin es almacenada de forma que pueda ser comprendida a
simple vista por el usuario. Por esta razn, tambin son llamados archivos de
texto plano. Ejemplos de este tipo de archivo son un documentos HTML, cdigo
fuente de programas en lenguajes de alto y bajo nivel, documentos de texto sin
formato (txt) y los archivos de configuracin de algunas aplicaciones.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
168
Archivos binarios
Un archivo binario es una secuencia de bytes, en el cual la informacin es
almacenada en la forma ms elemental que puede manejar un computador:
ceros y unos. Esto ocasiona que la misma no pueda ser comprendida a simple
vista por el usuario. Ejemplos de este tipo de archivo son imgenes y msica
digitalizada, programas en lenguaje de mquina, documentos con formato (doc,
pdf) y los archivos de configuracin de algunas aplicaciones.
Observe que los archivos de configuracin de las aplicaciones han sido
mencionados como ejemplo para ambos tipos de archivo. Esto lo que nos indica
es que en el fondo cualquier archivo puede ser almacenado en una u otra forma,
la decisin la toma el programador que disea la aplicacin que har uso del
archivo en cuestin, evalando previamente que tipo de archivo se adapta mejor
a sus necesidades. Por ejemplo, si el archivo de configuracin es binario ser
necesario crear una herramienta que permita al usuario final modificarlo,
mientras que si es un archivo de texto plano, el mismo podr ser modificado
mediante la utilizacin de un editor de texto convencional.
Tipos de acceso
Otro criterio utilizado para clasificar los diferentes tipos de archivo, se refiere a
la forma en la que se accesa a la informacin almacenada en los mismos. Desde
este punto de vista, un archivo puede ser de acceso secuencial o de acceso
aleatorio.
Acceso secuencial
En un archivo de acceso secuencial, para tener acceso al dato almacenado en la
posicin N, se deben haber accesado los datos almacenados en las N-1
posiciones previas, en un orden secuencial.
Acceso aleatorio
Un archivo de acceso aleatorio permite acceder a cualquier parte del mismo en
cualquier momento, como si se tratara de un arreglo almacenado en la
memoria. Por esta razn este tipo de acceso es conocido tambin como acceso
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
169
directo, ya que permite ir directamente a los datos de inters sin tener que
recorrer los que lo preceden dentro del archivo.
Como siempre, la decisin de utilizar un determinado tipo de acceso recae en el
programador. El criterio de mayor peso a la hora de elegir uno u otro es el
tiempo de acceso. Si existen pocos datos almacenados en un archivo, la
diferencia entre los tiempos de acceso de forma secuencial y directa puede ser
imperceptible para el usuario. Sin embargo, la diferencia comienza a apreciarse
a medida que se manejan archivos con grandes cantidades de informacin.
Sin embargo existen casos en los que el acceso secuencial de un archivo es
recomendable. El caso ms representativo es el manejo de una nmina de
empleados, clientes o estudiantes, en la cual se se deben procesar todos (o la
mayora) de los registros.
De scr ipc i n
fopen
Abre un archivo
fclose
Cierra un archivo
fread
fwrite
fgets
fputs
fscanf
fprintf
fseek
feof
ferror
fflush
remove
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
170
A continuacin se presenta una descripcin ms detallada de cada una de estas
llamadas al sistema:
fopen
La funcin fopen, permite abrir un archivo existente. El prototipo de la misma es
el siguiente:
Opc i n
De scr ipc i n
r+
Trunca el fichero a una longitud de cero bytes o crea uno nuevo si no existe, y lo abre
para para escritura. El apuntador se posiciona al principio.
w+
Trunca el fichero a una longitud de cero bytes o crea uno nuevo si no existe, y lo abre
para para lectura y escritura. El apuntador se posiciona al principio.
a+
Abre el archivo para lectura y escritura o crea uno nuevo si no existe. El apuntador se
posiciona al final
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
171
fclose
La funcin fclose, permite cerrar un archivo, es decir, elimina la relacin
existente entre el descriptor y el archivo, de forma que el primero deje de hacer
referencia al ltimo (note por lo tanto que el cerrar el descriptor no
necesariamente implica la liberacin de los recursos asociados al archivo, ya que
puede existir otro descriptor haciendo referencia al mismo). El prototipo de la
misma es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
172
fgets
La funcin fgets, permite leer una cadena de caracteres desde un archivo. El
prototipo de la misma es el siguiente:
char *fgets(char *s, int tam, FILE *flujo);
la
cantidad
de
elementos
reconocidos
asignados
correspondientes variables.
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
las
173
fprintf
La funcin fprintf, permite realizar escritura formateda en un archivo. El
prototipo de la misma es el siguiente:
int fprintf(FILE *flujo, const char *formato, ...);
funcin
fseek,
permite
cambiar
la
ubicacin
del
apuntador
de
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
174
ferror
La funcin ferror, permite determinar si ha ocurrido un error en al realizar
alguna operacin sobre un descriptor de archivo. El prototipo de la misma es el
siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
175
#include <stdio.h>
int main()
{
int opcion = 0;
FILE* archivo;
printf("1 Insertar contacto\n");
printf("2 Buscar contacto\n");
while(opcion!=1 && opcion !=2)
{
printf("Su opcin: ");
scanf("%d", &opcion);
}
char nombre[80];
int telefono;
int posicion;
if(opcion==1)
{
// Abrir el archivo de texto para escritura al final
archivo = fopen("agenda.txt","a");
// Si no se pudo abrir el archivo
if(archivo==NULL)
{
printf("Error al abrir el archivo\n");
return -1;
}
else
{
printf("Nombre del contacto: ");
scanf("%s", nombre);
printf("Telfono del contacto: ");
scanf("%d", &telefono);
fprintf(archivo, "%s | %d\n", nombre, telefono);
}
}
if(opcion==2)
{
// Abrir el archivo de texto para lectura desde el comienzo
archivo = fopen("agenda.txt","r");
// Si no se pudo abrir el archivo
if(archivo==NULL)
{
printf("Error al abrir el archivo\n");
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
176
return -1;
}
else
{
printf("Posicin: ");
scanf("%d", &posicion);
int i=0;
while(i!=posicion && i!=-1)
{
if(feof(archivo)) i=-1;
else
{
fscanf(archivo, "%s | %d\n", nombre, &telefono);
i++;
}
}
if(i==-1)
{
printf("La posicin indicada est vaca\n");
}
else
{
printf("Nombre: %s\n", nombre);
printf("Telefono: %d\n", telefono);
}
}
// Cerrar el archivo
fclose(archivo);
return 0;
}
}
Programa en ensamblador:
.section .rodata
cad1:
.asciz "1 Insertar contacto\n2 Buscar contacto\n"
cad2:
.asciz "Su opcin: "
cad3:
.asciz "Ocurri un error al intentar abrir el archivo\n"
cad4:
.asciz "Nombre del contacto: "
cad5:
.asciz "Telfono del contacto: "
cad6:
.asciz "Posicin: "
cad7:
.asciz "Nombre: %s\nTelefono: %d\n"
cad8:
.asciz "La posicin indicada est vaca\n"
file:
.asciz "agenda.txt"
format1:.asciz "%d"
format2:.asciz "%s"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
177
format3:.asciz "%s | %d\n"
modo1: .asciz "a"
modo2: .asciz "r"
.section .bss
nombre: .space
tlf:
.space
opcion: .space
pos:
.space
desp:
.space
fd: .space 4
80
4
4
4
4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
while: pushl $cad2
call printf
addl $4, %esp
pushl $opcion
pushl $format1
call scanf
addl $8, %esp
# Si es 1 salta a insertar
# Si es 2 salta a buscar
# En otro caso pregunta de nuevo
# Modo: ab
# Archivo: agenda2.dat
# Llama a fopen
mov %eax, fd
cmpl $0, fd
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
178
je error
pushl $cad4
call printf
addl $4, %esp
pushl $nombre
pushl $format2
call scanf
addl $8, %esp
pushl $cad5
call printf
addl $4, %esp
pushl $tlf
pushl $format1
call scanf
addl $8, %esp
#
#
#
#
#
Telefono
&Nombre
Cadena de formato
Apuntador al archivo abierto
Llama a fprintf
jmp fin
cmpl $0, fd
je error
pushl $cad6
call printf
addl $4, %esp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
179
pushl $pos
pushl $format1
call scanf
addl $8, %esp
# i=0
# Si i=pos
# Salta a mostrar
rep:
# i++
# Repite la bsqueda
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
180
pushl $cad3
call printf
addl $4, %esp
jmp fin2
fin:
# Cierra el archivo si estaba abierto
pushl fd
# Descriptor del archivo a cerrar
call fclose
# Llama a fclose
addl $4, %esp
fin2:
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
181
scanf("%d", &opcion);
}
char nombre[80];
int telefono;
int posicion;
if(opcion==1)
{
// Abrir el archivo binario para escritura al final
archivo = fopen("agenda2.dat","ab");
// Si no se pudo abrir el archivo
if(archivo==NULL)
{
printf("Error al abrir el archivo\n");
return -1;
}
else
{
printf("Nombre del contacto: ");
scanf("%s", nombre);
printf("Telfono del contacto: ");
scanf("%d", &telefono);
fwrite(nombre, 80, 1, archivo);
fwrite(&telefono, 4, 1, archivo);
}
}
if(opcion==2)
{
// Abrir el archivo binario para lectura desde el comienzo
archivo = fopen("agenda2.dat","rb");
// Si no se pudo abrir el archivo
if(archivo==NULL)
{
printf("Error al abrir el archivo\n");
return -1;
}
else
{
printf("Posicin: ");
scanf("%d", &posicion);
fseek(archivo,84*(posicion-1),SEEK_SET);
fread(nombre, 80, 1, archivo);
fread(&telefono, 4, 1, archivo);
if(feof(archivo))
{
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
182
printf("La posicin indicada est vaca\n");
}
else
{
printf("Nombre: %s\n", nombre);
printf("Telefono: %d\n", telefono);
}
}
// Cerrar el archivo
fclose(archivo);
return 0;
}
}
Programa en ensamblador:
.section .rodata
cad1:
.asciz "1 Insertar contacto\n2 Buscar contacto\n"
cad2:
.asciz "Su opcin: "
cad3:
.asciz "Ocurri un error al intentar abrir el archivo\n"
cad4:
.asciz "Nombre del contacto: "
cad5:
.asciz "Telfono del contacto: "
cad6:
.asciz "Posicin: "
cad7:
.asciz "Nombre: %s\nTelefono: %d\n"
cad8:
.asciz "La posicin indicada est vaca\n"
file:
.asciz "agenda2.dat"
format1:.asciz "%d"
format2:.asciz "%s"
modo1: .asciz "ab"
modo2: .asciz "rb"
.section .bss
nombre: .space
tlf:
.space
opcion: .space
pos:
.space
desp:
.space
fd: .space 4
80
4
4
4
4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
183
while: pushl $cad2
call printf
addl $4, %esp
pushl $opcion
pushl $format1
call scanf
addl $8, %esp
# Si es 1 salta a insertar
# Si es 2 salta a buscar
# En otro caso pregunta de nuevo
# Modo: ab
# Archivo: agenda2.dat
# Llama a fopen
mov %eax, fd
cmpl $0, fd
je error
pushl $cad4
call printf
addl $4, %esp
pushl $nombre
pushl $format2
call scanf
addl $8, %esp
pushl $cad5
call printf
addl $4, %esp
pushl $tlf
pushl $format1
call scanf
addl $8, %esp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
184
# Inserta el contacto en el archivo
pushl fd
pushl $1
pushl $80
pushl $nombre
call fwrite
addl $16, %esp
#
#
#
#
#
pushl fd
pushl $1
pushl $4
pushl $tlf
call fwrite
addl $16, %esp
#
#
#
#
#
jmp fin
cmpl $0, fd
je error
pushl $cad6
call printf
addl $4, %esp
pushl $pos
pushl $format1
call scanf
addl $8, %esp
decl pos
movl $84, %eax
imull pos
movl %eax, desp
# desplazamiento = (posicin-1)*84
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
185
pushl fd
call fseek
addl $12, %esp
#
#
#
#
#
pushl tlf
pushl $nombre
pushl $cad7
call printf
addl $12, %esp
jmp fin
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
186
addl $4, %esp
jmp fin2
fin:
# Cierra el archivo si estaba abierto
pushl fd
# Descriptor del archivo a cerrar
call fclose
# Llama a fclose
addl $4, %esp
fin2:
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
Observe que en esta nueva versin no es necesario recorrer todo el archivo para
recuperar la informacin de un contacto, ya que al conocer a priori el tamao en
bytes que ocupa cada registro dentro del archivo (84 bytes) es posible
posicionar el apuntador de lectura en el desplazamiento adecuado para leer
nicamente la informacin de inters. Note tambin que si intenta examinar el
contenido del archivo agenda.dat en un editor de texto, encontrar imposible
determinar el nmero telefnico de los contactos. Esto se debe a que los
mismos estn almacenados en formato binario como enteros de 4 bytes.
Llamadas al sistema
Todas las funciones de alto nivel descritas en la seccin anterior se apoyan en
las llamadas al sistema operativo para llevar a cabo cada una de las operaciones
involucradas con el manejo de archivos. Las mismas pueden ser utilizadas
directamente por un programa en lenguaje ensamblador, siguiendo los pasos
descritos en el capitulo 6.
El sistema operativo Linux presenta una gran variedad de llamadas relacionadas
con el manejo de archivos. La siguiente es una lista de las ms relevantes, junto
con una breve descripcin de la tarea que realiza cada una de ellas:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
187
Llam ad a
Nmer o
De scr ipc i n
creat
open
Abre un archivo
close
Cierra un archivo
read
write
lseek
19
10
mkdir
39
Crea un directorio
rmdir
40
rename
38
chmod
15
chdir
12
unlink
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
188
En donde camino es una cadena que contiene la ruta (absoluta o relativa) del
archivo que se desea abrir y flags es un entero que representa las caractersticas
con las que se desea operar el archivo a abrir (por ejemplo solo lectura, solo
escritura, etc.) En este caso el atributo modo es opcional, y tiene la misma
utilidad que en el caso de la llamada creat en caso de que el archivo a abrir no
exista y la bandera O_CREAT est encendida. La llamada devuelve el descriptor
asociado al archivo abierto. En caso de no poderse abrir el archivo, la llamada
devuelve un valor negativo que identifica al error ocurrido.
Las diferentes banderas que componen el atributo flags se encuentran definidas
en
el
archivo
fcntl.h,
generalmente
ubicado
en
el
directorio
Ba nd era
Valor (oc ta l)
De scr ipc i n
O_RDONLY
00
Solo lectura
O_WRONLY
01
Solo escritura
O_RDWR
02
Lectura y escritura
O_CREAT
0100
O_TRUNK
01000
O_APPEND
02000
close
La llamada al sistema close (6), permite cerrar un archivo, es decir, elimina la
relacin existente entre el descriptor y el archivo, de forma que el primero deje
de hacer referencia al ltimo (note por lo tanto que el cerrar el descriptor no
necesariamente implica la liberacin de los recursos asociados al archivo, ya que
puede existir otro descriptor haciendo referencia al mismo). El prototipo de la
llamada close es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
189
read
La llamada al sistema read (4), permite leer datos desde un archivo. El prototipo
de la llamada read es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
190
una operacin de escritura, los bytes ubicados entre el antiguo final del archivo
y la posicin actual son rellenados con cero.
unlink
La llamada al sistema unlink (10), permite eliminar una entrada del sistema de
archivos, y de ser la nica referencia al archivo en cuestin, eliminarlo. El
prototipo de la llamada unlink es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
191
rename
La llamada al sistema rename (38), permite cambiar el nombre (y en
consecuencia mover) un archivo o directorio existente. El prototipo de la
llamada rename es el siguiente:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
192
Programa en ensamblador:
.section .rodata
cad1:
.asciz "1 Insertar contacto\n2 Buscar contacto\n"
cad2:
.asciz "Su opcin: "
cad3:
.asciz "Ocurri un error al intentar abrir el archivo\n"
cad4:
.asciz "Nombre del contacto: "
cad5:
.asciz "Telfono del contacto: "
cad6:
.asciz "Posicin: "
cad7:
.asciz "Nombre: %s\nTelefono: %d\n"
cad8:
.asciz "La posicin indicada est vaca\n"
file:
.asciz "agenda3.dat"
format1:.asciz "%d"
format2:.asciz "%s"
.section .bss
nombre: .space
tlf:
.space
opcion: .space
pos:
.space
desp:
.space
fd:
.space
80
4
4
4
4
4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
while:
pushl $cad2
call printf
addl $4, %esp
pushl $opcion
pushl $format1
call scanf
addl $8, %esp
# Si es 1 salta a insertar
# Si es 2 salta a buscar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
193
jmp while
pushl $cad4
call printf
addl $4, %esp
pushl $nombre
pushl $format2
call scanf
addl $8, %esp
pushl $cad5
call printf
addl $4, %esp
pushl $tlf
pushl $format1
call scanf
addl $8, %esp
# Inserta el contacto
movl $4, %eax
#
movl fd, %ebx
#
movl $nombre, %ecx #
movl $84, %edx
#
int $0x80
#
jmp fin
en el archivo
Servicio #4, (write)
File Descriptor del archivo abierto
Apuntador a los datos a escribir
Nmero de bytes a escribir
Llamada al SO
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
194
int $0x80
mov %eax, fd
# Llamada al SO
# Apuntador al archivo abierto
cmpl $0, fd
jl error
pushl $cad6
call printf
addl $4, %esp
pushl $pos
pushl $format1
call scanf
addl $8, %esp
decl pos
movl $84, %eax
imull pos
movl %eax, desp
# desplazamiento = (posicin-1)*84
pushl tlf
pushl $nombre
pushl $cad7
call printf
addl $12, %esp
jmp fin
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
195
pushl $cad8
call printf
addl $4, %esp
jmp fin
si estaba abierto
# Servicio #5 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
196
Ejercicios
12.1 El comando more muestra el contenido de un archivo de texto,
permitiendo al usuario avanzar una lnea presionando la tecla ENTER o a la
siguiente pgina presionando la barra espaciadora. Escriba un programa que
simule este comportamiento. Utilice las funciones de alto nivel provistas por el
lenguaje C.
12.2- Repita el ejercicio anterior utilizando nicamente llamadas al sistema
operativo.
12.3 Modifique la primera versin de la agenda telefnica (acceso secuencial,
texto plano, funciones de C), de forma que incluya una opcin para eliminar un
contacto.
12.4 Repita el ejercicio anterior para la tercera versin de la agenda (acceso
directo, archivo binario, llamadas al sistema).
12.5 Escriba un programa que dados dos archivos de texto, produzca como
salida un tercer archivo que sea la concatenacin de los contenidos de ambos.
Utilice las funciones de alto nivel provistas por el lenguaje C.
12.6 Escriba un programa que dados dos archivos binarios con el formato
utilizado por la agenda telefnica desarrollada en este captulo, produzca como
salida un nuevo archivo binario que contenga la mezcla de los contactos
contenidos en ambos. Asuma que dentro de un mismo archivo no existen
contactos repetidos. Utilice nicamente llamadas al sistema operativo. Ayuda:
Al comparar los nombres de los contactos solo tenga en cuenta la parte de la
cadena que precede al carcter nulo (/0).
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
197
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
%ea x
5
%eb x
%ecx
%ed x
0
6
11
6
2
7
14
8
3
25
25
8
1
0
1
0
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
198
b:
c:
d:
x:
.long
.long
.long
.long
8
12
4
0
.section .text
.globl _start
_start:
movl b, %ebx
imull $3, %ebx
movl a, %eax
subl %ebx, %eax
movl c, %ecx
subl d, %ecx
imull $25,%ecx
addl %ecx, %eax
movl %eax, x
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
%ebx=b
%ebx=3b
%eax=a
%eax=a-3b
%ecx=c
%ecx=c-d
%ecx=(c-d)*25
%eax= (a-3b)+((c-d)*25)
guarda el resultado en x
# %eax=b
# %eax=b-c
%eax=(b-c)+a
# %ecx=c
# %ecx=c*d
# %edx=0
# %eax=((b-c)+a)/(c*d)
%edx=resto
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
199
movl %eax, x
# guarda el resultado en x
#
#
#
#
#
#
compara a con b
si a>b salata a amayorb
compara b con c
si b<c salta a mnenorc
cuando b es el mayor
salta a fin
bmenorc:
# cuando c es el mayor
# salta a fin
amayorb:
#
#
#
#
amenorc:
# cuando c es el mayor
fin:
compara a con c
si a<c salta a amenorc
cuando a es el mayor
salta a fin
5.7# Programa que produce como salida a si a =b; a-b si a>b o b-a si a<b
.section .data
a:
.long 6
# declaracin de las variables a y b
b:
.long 8
resultado:
.long 0
# variable resultado para guardar la salida
.section .text
.globl _start
_start:
movl a, %eax
# %eax= a
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
200
movl b, %ebx
# %ebx= b
cmpl %ebx, %eax
# compara a con b
je igual
# si a=b salta a igual
jg mayor
# si a>b salta a mayor
subl %eax, %ebx
# cuando a<b, resta b-a
movl %ebx, resultado
# actualiza el resultado
jmp fin
# salta a fin de programa
movl %eax, resultado
# cuando a=b resultado=a
jmp fin
# salta a fin de programa
subl %ebx, %eax
# cuando a>b, resta a-b
movl %eax, resultado
# actualiza el resultado
movl $1, %eax
# culmina el programa
movl $0, %ebx
int $0x80
igual:
mayor:
fin:
5.81
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
%ea x
25
30
%eb x
%ecx
%ed x
%es p
0x0FC
31
0xF08
31
15
0
1
2
1
31
30
0xF04
0xF08
0xF0C
0x100
Pila:
Direccin
Contenido
0xF04
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
201
0xF08
31
0x0FC
30
0x100
Captulo 6
6.1.# Programa que muestra valores enteros en diferentes formatos
.section .data
mensaje:
.asciz"Programa que lee 6 valores y los muestra en uno de cuatro
formatos\n"
mensaj2:
.asciz"Los formatos disponibles para mostrar los numeros son:\n"
f1:
.asciz"Horizontal en el mismo orden de entrada [1]\n"
f2:
.asciz"Horizontal en orden inverso
[2]\n"
f3:
.asciz"Vertical en el mismo orden de entrada
[3]\n"
f4:
.asciz"Vertical en orden inverso
[4]\n"
escoge:
.asciz"Escoja un formato, introduzca el numero correspondiente:\t"
leer:
.asciz"Introduzca los 6 valores:\n"
v1:
.asciz"valor 1:\t"
v2:
.asciz"valor 2:\t"
v3:
.asciz"valor 3:\t"
v4:
.asciz"valor 4:\t"
v5:
.asciz"valor 5:\t"
v6:
.asciz"valor 6:\t"
salta:
.asciz"\n\n"
valor:
.asciz"%d"
salf12:
.asciz"Los valores leidos son: \n %d\t %d\t %d\t %d\t %d\t %d\n"
salf34:
.asciz"Los valores leidos son: \n %d\n %d\n %d\n %d\n %d\n %d\n"
forma:
.long 0
val1:
.long 0
val2:
.long 0
val3:
.long 0
val4:
.long 0
val5:
.long 0
val6:
.long 0
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $mensaj2
call printf
pushl $f1
call printf
pushl $f2
call printf
pushl $f3
call printf
pushl $f4
# mensaje inicial
#
formatos disponibles
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
202
call printf
addl $24, %esp
pushl $escoge
call printf
pushl $forma
pushl $valor
call scanf
pushl $leer
call printf
addl $16, %esp
pushl $v1
call printf
pushl $val1
pushl $valor
call scanf
addl $12, %esp
# lee valor 1
pushl $v2
call printf
pushl $val2
pushl $valor
call scanf
addl $12, %esp
# lee valor 2
pushl $v3
call printf
pushl $val3
pushl $valor
call scanf
addl $12, %esp
# lee valor 3
pushl $v4
call printf
pushl $val4
pushl $valor
call scanf
addl $12, %esp
# lee valor 4
pushl $v5
call printf
pushl $val5
pushl $valor
call scanf
addl $12, %esp
# lee valor 5
pushl $v6
call printf
pushl $val6
pushl $valor
call scanf
# lee valor 6
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
203
addl $12, %esp
pushl $salta # salto de lnea
call printf
addl $4, %esp
cmpl $1, forma
je uno
cmpl $2, forma
je dos
cmpl $3, forma
je tres
pushl val1
pushl val2
pushl val3
pushl val4
pushl val5
pushl val6
pushl $salf34
call printf
jmp fin
uno:
pushl val6
pushl val5
pushl val4
pushl val3
pushl val2
pushl val1
pushl $salf12
call printf
jmp fin
dos:
pushl val1
pushl val2
pushl val3
pushl val4
pushl val5
pushl val6
pushl $salf12
call printf
jmp fin
tres:
pushl val6
pushl val5
pushl val4
pushl val3
pushl val2
pushl val1
pushl $salf34
call printf
fin:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
204
xorl %ebx, %ebx
int $0x80
.long
.long
.long
.long
0
0
0
0
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $leer
call printf
addl $8, %esp
# mensaje inicial
pushl $v1
call printf
pushl $val1
pushl $valor
call scanf
addl $12, %esp
# lee valor 1
pushl $v2
call printf
pushl $val2
pushl $valor
call scanf
addl $12, %esp
# lee valor 2
pushl $v3
call printf
pushl $val3
pushl $valor
call scanf
addl $12, %esp
# lee valor 3
pushl $v4
call printf
pushl $val4
# lee valor 4
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
205
pushl $valor
call scanf
addl $12, %esp
pushl $salta # salto de lnea
call printf
addl $4, %esp
movl
addl
addl
addl
val1,
val2,
val3,
val4,
%eax
%eax
%eax
%eax
pushl %eax
pushl val4
pushl val3
pushl val2
pushl val1
pushl $salida
call printf
6.3..section .data
mensaje:
.asciz"Programa que lee 4 valores y calcula el promedio\n"
leer:
.asciz"Introduzca los 4 valores:\n"
v1:
.asciz"valor 1:\t"
v2:
.asciz"valor 2:\t"
v3:
.asciz"valor 3:\t"
v4:
.asciz"valor 4:\t"
salta: .asciz"\n"
valor: .asciz"%d"
salida:
.asciz"El promedio de: %d , %d , %d , %d es: %d\n"
val1:
val2:
val3:
val4:
.long
.long
.long
.long
0
0
0
0
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $leer
call printf
addl $8, %esp
pushl $v1
call printf
pushl $val1
# mensaje inicial
# lee valor 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
206
pushl $valor
call scanf
addl $12, %esp
pushl $v2
call printf
pushl $val2
pushl $valor
call scanf
addl $12, %esp
# lee valor 2
pushl $v3
call printf
pushl $val3
pushl $valor
call scanf
addl $12, %esp
# lee valor 3
pushl $v4
call printf
pushl $val4
pushl $valor
call scanf
addl $12, %esp
# lee valor 4
pushl %eax
pushl val4
pushl val3
pushl val2
pushl val1
pushl $salida
call printf
6.4# Programa que lee dos valores a y b y produce como salida, por
# pantalla a si a =b; a-b si a>b o b-a si a<b
.section .data
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
207
leea:
.asciz"Introduzca el dato a:
leeb:
.asciz"Introduzca el dato b:
valor: .asciz"%d"
a:
.long 0
b:
.long 0
salida:
.asciz"resultado:
%d\n"
.section .text
.globl _start
_start:
leal a, %eax
pushl %eax
pushl $valor
call scanf
leal b, %eax
pushl %eax
pushl $valor
call scanf
movl a, %eax
movl b, %ebx
xorl %ecx, %ecx
cmpl %ebx, %eax
je igual
jg mayor
subl %eax, %ebx
movl %ebx, %ecx
jmp fin
igual: movl %eax, %ecx
jmp fin
mayor: subl %ebx, %eax
movl %eax, %ecx
fin:
pushl %ecx
pushl $salida
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
\n"
\n"
%eax=dir inicial de a
pasa la dir de a como parametro
pasa el formato valor como parametro
llamada a la funcin de lectura (lee a)
%eax=dir inicial de b
pasa la dir de b como parametro
pasa el formato valor como parametro
llamada a la funcin de lectura (lee b)
%eax=a
%ebx=b
%ecx=0 temporal para el resultado
compara a con b
si a=b salta a igual
si a>b salta a mayor
resta b-a
guarda resultado en %ecx
salta a fin de programa
cuando a=b, %ecx=a
salta a fin de programa
cuando a>b, resta a-b
guarda resultado en %ecx
pasa %ecx como parametro
apila formato de salida
muestra resultado por pantalla
fin del programa
6.5# Programa que calcula el monto a pagar para una llamada telefonica
.section .data
leea:
.asciz"Introduzca los minutos de la llamada:
\n"
valor:
.asciz"%d"
min:
.long 0
monto:
.asciz"Monto a pagar:
%d\n"
.section .text
.globl _start
_start:
leal min, %eax
pushl %eax
pushl $valor
call scanf
xorl %ebx, %ebx
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
208
basico:
fin:
6.6..section .rodata
cadinic:
.asciz
caracter1:
.asciz
caracter2:
.asciz
cadmod:
.asciz
fcadmod:
.section
cadena:
car1:
car2:
trash:
.bss
.space
.space
.space
.space
20
1
1
10
#
#
#
#
#
espacio
espacio
espacio
espacio
nuestro
para la cadena
para el caracter a reemplazar
para el nuevo caracter
para volcar los caracteres que no son de
inters
.section .text
.globl _start
_start:
# Mensaje solicitando que se escriba la cadena
movl $4, %eax
# Servicio #4 (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cadinic, %ecx
# Apuntador a la cadena a imprimir
movl $caracter1-cadinic, %edx # Nmero de caracteres a imprimir
int $0x80
# Llamada al SO
# Lectura de la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (servicio de lectura)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Dir donde se almacenar la cadena
movl $20, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Mensaje que solicita caracter a reemplazar
movl $4, %eax
# Servicio #4 (write)
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
209
movl $1, %ebx
leal caracter1, %ecx
movl $caracter2-caracter1,%edx
int $0x80
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
210
fincomp:
# Imprimir resultado (Mensaje)
movl $4, %eax
movl $1, %ebx
leal cadmod, %ecx
movl $fcadmod-cadmod, %edx
int $0x80
#
#
#
#
#
Servicio #4 (write)
File Descriptor = 1 (stdout)
Apuntador a la cadena a imprimir
Nmero de caracteres a imprimir
Llamada al SO
6.7..section
cad1:
cad2:
cadena:
fcadena:
.data
.asciz "Por favor introduzca una cadena: "
.asciz "La cadena introducida es: "
.space 50
# Reserva espacio para la cadena introducida
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando que se escriba una cadena
movl $4, %eax
# Servicio #4 (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad1, %ecx
# Apuntador a la cadena a imprimir
movl $cad2-cad1, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (servicio de lectura)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Muestra el resultado (una sola llamada)
movl $4, %eax
# Servicio #4 (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad2, %ecx
# Apuntador a la cadena a imprimir
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
211
movl $fcadena-cad2, %edx
int $0x80
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
.space 10
.space 32
# base decimal
# base binaria
Por:
Para facilitar este ltimo cambio, y permitir que el programa funcione de forma
genrica para otras bases, es posible definir una constante simblica:
.equ BASE, 2
# Se utiliza base 2
# base binaria
Esta solucin es vlida para cualquier base comprendida entre 2 y 10. Para
bases superiores a 10 es necesario introducir lgica adicional que contemple el
hecho de que los dgitos superiores al 9 son representados mediante las letras
del alfabeto. A continuacin se presenta el programa con las modificaciones
sugeridas anteriormente:
.equ BASE, 2
# Se utiliza base 2
.section .rodata
cad1:
.asciz "Valor de A: "
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
212
cad2:
cad3:
salto:
.section
A:
B:
C:
cadena:
.bss
.space
.space
.space
.space
4
4
4
32
#
#
#
#
Reserva
Reserva
Reserva
Reserva
espacio
espacio
espacio
espacio
para
para
para
para
un
un
un
la
entero
entero
entero
cadena introducida
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando que proporcione el valor de A
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad1, %ecx
# Apuntador a la cadena a imprimir
movl $cad2-cad1, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (read)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Obtiene el valor entero representado por la cadena
xorl %ecx, %ecx
# i=0
xorl %eax, %eax
# A=0
movl $BASE, %esi
# base
for1:
movb cadena(%ecx), %bl # Carga un caracter. (cadena[i])
cmpb $0, %bl
# Si llega al final de la cadena
je ffor1
# Sale del ciclo
cmpb $10, %bl
# Si llega al final de la cadena
je ffor1
# Sale del ciclo
subb $'0', %bl
# Obtiene el dgito entero que representa
movzx %bl, %ebx
# Expande el entero a 32 bits (D)
mull %esi
# A=A*10
addl %ebx, %eax
# A=A+D
incl %ecx
# Se repite para el siguiente caracter
jmp for1
ffor1:
movl %eax, A
# Guarda el valor de A
# Muestra un mensaje solicitando que proporcione el valor de A
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad2, %ecx
# Apuntador a la cadena a imprimir
movl $cad3-cad2, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
213
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
decimal
214
int $0x80
# Llamada al SO
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
6.9..section .rodata
cad1:
.asciz "Por favor introduzca un entero decimal con signo: "
cad2:
.asciz "El valor del entero introducido es: %d\n"
.section
NUM:
SIGNO:
cadena:
.bss
.space 4
.space 4
.space 12
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando que proporcione el valor del entero
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal cad1, %ecx
# Apuntador a la cadena a imprimir
movl $cad2-cad1, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (read)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
215
# Obtiene el valor entero representado por la cadena
xorl %ecx, %ecx
xorl %eax, %eax
movl $10, %esi
# i=0
# A=0
# base decimal
negativo:
movl $-1, SIGNO
incl %ecx
for1:
movb cadena(%ecx), %bl
cmpb $0, %bl
je ffor1
cmpb $10, %bl
je ffor1
subb $'0', %bl
movzx %bl, %ebx
mull %esi
addl %ebx, %eax
incl %ecx
jmp for1
ffor1:
imull SIGNO
movl %eax, NUM
#
#
#
#
#
#
#
#
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
216
.section
params:
format:
msj:
msj2:
.rodata
.long string, char
.asciz "Soy %s y me gusta la letra %c"
.asciz "Cadena de entrada: "
.asciz "Eres %s y te gusta la letra %c\n"
.section
char:
string:
cadena:
.bss
.space 10
.space 20
.space 100
# Variable char
# Variable string
# Reserva espacio para la cadena introducida
.section .text
.globl _start
_start:
# Muestra un mensaje solicitando la cadena de entrada
movl $4, %eax
# Servicio #4, (write)
movl $1, %ebx
# File Descriptor = 1 (stdout)
leal msj, %ecx
# Apuntador a la cadena a imprimir
movl $msj2-msj, %edx
# Nmero mximo de caracteres a imprimir
int $0x80
# Llamada al SO
# Lee la cadena introducida por el usuario
movl $3, %eax
# Servicio #3, (read)
movl $0, %ebx
# File Descriptor = 0 (stdin)
leal cadena, %ecx
# Direccin donde se almacenar la cadena
movl $49, %edx
# Nmero mximo de caracteres a leer
int $0x80
# Llamada al SO
# Ciclo para buscar especificadores de formato
xorl %esi, %esi
# i=0
xorl %edi, %edi
# j=0
xorl %ecx, %ecx
# reconocidos=0
buscar:
movb format(%esi), %al
# Carga un caracter de la cadena de formato
cmpb $'\0', %al
# Si es un caracter nulo
je fbuscar
# Alcanz el final de la cadena de formato
cmpb $'%', %al
# Si es un smbolo de porcentaje
je reconocer
# Debe reconocer una variable
cmpb cadena(%edi), %al
# De lo contrario, debe coincidir con
jne fbuscar
# la cadena proporcionada por el usuario
incl %esi
incl %edi
jmp buscar
reconocer:
incl %esi
movb format(%esi), %al
cmpb $'c', %al
je recon_c
cmpb $'s', %al
je recon_s
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
217
jmp error
recon_c:
movb
movl
movb
incl
cadena(%edi), %al
params(,%ecx,4),%edx
%al, (%edx)
%edx
incl %ecx
incl %esi
incl %edi
jmp buscar
recon_s:
incl %esi
movb format(%esi), %bl
movl params(,%ecx,4),%edx
ciclo:
movb cadena(%edi), %al
cmpb %al, %bl
je fciclo
movb %al, (%edx)
incl %edi
incl %edx
jmp ciclo
fciclo:
movb $0, (%edx)
incl %ecx
incl %esi
incl %edi
jmp buscar
# Especificador invlido
# Caracter reconocido
# Direccin destino
# Almacena el caracter
# reconocidos++
# Contina procesando la cadena de formato
# Cierra la cadena
# reconocidos++
# Contina procesando la cadena de formato
fbuscar:
# Muestra las variables reconocidas por el 'scanf'
pushl char
pushl $string
pushl $msj2
call printf
addl $12, %esp
# Termina el programa
movl $1, %eax
movl $0, %ebx
int $0x80
6.11..section
fkeys:
CADP:
CADL:
ERROR:
.data
.byte 59,60,61,62,63,0,1,2,3,4,23,24
.asciz "\rSe ha presionado la tecla F%d\n"
.asciz "\rSe ha levantado la tecla F%d\n"
.asciz "Se ha denegado el permiso sobre los puertos del teclado\n"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
218
.section .bss
SC:
.space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
jne err
%eax,%eax
espera:
inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
# No se obtuvo el permiso
# Limpia eax
# Lee el scancode del registro de datos
# Si es ENTER (presionada) terminar
movb %al, SC
andb $0x80, %al
je pres
lev:
# Contina la bsqueda
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
219
mostrar:
incl %ecx
pushl %ecx
pushl %ebx
call printf
addl $8, %esp
jmp espera
# Muestra la tecla
# Termina el programa
6.12..section
fkeys:
CAD:
CADP:
CADL:
ERROR:
.data
.byte 59,60,61,62,63,0,1,2,3,4,23,24
.asciz "\r
"
.asciz "\rSe ha presionado la tecla F%d\n"
.asciz "\rSe ha levantado la tecla F%d\n"
.asciz "Se ha denegado el permiso sobre los puertos del teclado\n"
.section .bss
SC:
.space 1
LASTSC: .space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
jne err
%eax,%eax
espera:
inb $0x64, %al
# No se obtuvo el permiso
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
220
andb $1, %al
cmpb $0, %al
je espera
# Enmascara el bit 0
# Si est apagado espera
# Limpia eax
# Lee el scancode del registro de datos
# Si es ENTER (presionada) terminar
# Contina la bsqueda
# Muestra la tecla
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
221
err: pushl $ERROR
call printf
addl $4, %esp
# Termina el programa
6.13..section
ALT:
CTRL:
Q:
.data
.long 0
.long 0
.long 0
BLANCO:
MSJ:
ERROR:
.asciz "\r
\r"
.asciz "\rSe ha presionado la combinacin ALT+CTRL+Q\n"
.asciz "Se ha denegado el permiso sobre los puertos del teclado\n"
.section .bss
SC:
.space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
jne err
%eax,%eax
espera:
inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
xorl %eax, %eax
inb $0x60,%al
cmpb $0x1C,%al
# No se obtuvo el permiso
# Limpia eax
# Lee el scancode del registro de datos
# Si es ENTER (presionada) terminar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
222
je fin
cmpb $0x1D,%al
je presiono_alt
cmpb $0x38,%al
je presiono_ctrl
cmpb $0x10,%al
je presiono_q
cmpb $0x9D,%al
je levanto_alt
cmpb $0xb8,%al
je levanto_ctrl
cmpb $0x90,%al
je levanto_q
# Si no se cumple la combinacin
# Espera por otra tecla
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
223
movl $1, %ebx
leal BLANCO, %ecx
movl $MSJ-BLANCO, %edx
int $0x80
jmp espera
err: pushl $ERROR
call printf
addl $4, %esp
#
#
#
#
# Termina el programa
6.14..section
TABLE:
ACUM:
AUX:
MSJ:
OPER:
SALTO:
ERROR:
.data
.byte 0b000, 0b001, 0b100, 0b101, 0b010,0b011,0b110,0b111
.byte 0, '\n'
# Acumulador de la calculadora binaria
.byte 0, '\n'
# Operando proporcionado por el usuario
.asciz "\r
\r"
.ascii "
\r"
.byte '\n'
.asciz "Se ha denegado el permiso sobre los puertos del teclado\n"
.bss
SC: .space 1
.section .text
.globl _start
_start:
# Solicita permiso sobre los puertos del teclado
movl $101, %eax
# Servicio 101 (ioperm)
movl $0x60, %ebx
# Desde 0x60 (Registro de datos)
movl $5, %ecx
# Hasta 0x64 (Registro de estado)
movl $1, %edx
# Obtener permiso
int $0x80
# Llamada al SO
testl
jne err
%eax,%eax
# No se obtuvo el permiso
# Caracteres reconocidos
jmp mostrar
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
224
espera:
inb $0x64, %al
andb $1, %al
cmpb $0, %al
je espera
xorl %eax, %eax
inb $0x60,%al
cmpb $0x1C,%al
je fin
movb %al, SC
andb $0x80, SC
jne espera
cmpl $0, %esi
jne bit
operacion:
cmpb $78,%al
je presiono_or
cmpb $55,%al
je presiono_and
# Limpia eax
# Lee el scancode del registro de datos
# Si es ENTER (presionada) terminar
# Si se presion la tecla +
# Si se presion la tecla *
# Si se presion la tecla 0
# Si se presion la tecla 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
225
movb $'*', OPER
incl %esi
comprueba:
cmpl $4, %esi
je opera
imprime:
movl $4, %eax
movl $1, %ebx
leal MSJ, %ecx
movl $SALTO-MSJ, %edx
int $0x80
jmp espera
opera:
movb AUX, %al
cmpb $'+', OPER
je ejecuta_or
ejecuta_and:
andb %al, ACUM
jmp seguir
#
#
#
#
#
# Carga el operador (+ o *)
# Si es +
# Se ejecuta un OR
ejecuta_or:
orb %al, ACUM
seguir:
movl $4, %eax
movl $1, %ebx
leal MSJ, %ecx
movl $ERROR-MSJ, %edx
int $0x80
#
#
#
#
#
mostrar:
inb $0x64, %al
andb $2, %al
jne mostrar
movb
outb
movb
leal
xlat
outb
$0xED, %al
%al,$0x60
ACUM, %al
TABLE, %ebx
%al,$0x60
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
226
jmp espera
err: pushl $ERROR
call printf
addl $4, %esp
# Termina el programa
Captulo 7
7.1# Programa que imprime Hola horizontal
.section .data
salida:
.asciz"Hola\t"
leenum:
.asciz"%d"
salta: .asciz"\n"
numero:
.long 0
.section .text
.globl _start
_start:
leal numero, %eax
pushl %eax
pushl $leenum
call scanf
ciclo:
cmpl $0, numero
je fin
pushl $salida
call printf
decl numero
jmp ciclo
fin:
pushl $salta
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
# lee numero
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
227
numero:
.long 0
.section .text
.globl _start
_start:
leal numero, %eax
pushl %eax
pushl $leenum
call scanf
ciclo:
cmpl $0, numero
je fin
pushl $salida
call printf
decl numero
jmp ciclo
fin:
movl $1, %eax
movl $0, %ebx
int $0x80
# Mensaje inicial
# Introducir dato de la base
# Leer base
# Introducir la potencia
# Leer potencia
# %eax = 0
# compara %eax con 0
# si x=0 resultado=0
# %eax=1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
228
mult:
fin:
movl y, %ecx
# %ecx=y tiene la potencia
cmpl $0, %ecx
# compara y con 0
je fin
# si y=0 termina
imull x, %eax
# multiplica la base y veces
decl %ecx
# decrementa potencia
jmp mult
# regresa al inicio del ciclo
pushl %eax
# Muestra el resultado
pushl y
pushl x
pushl $result
call printf
movl $1, %eax
# termina el programa
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
229
pushl $entrada
call scanf
addl $28, %esp
pushl $leer
call printf
pushl $horas
pushl $entrada
call scanf
addl $16, %esp
pushl $salta
call printf
addl $4, %esp
movl horas, %eax
cmpl $40, %eax
jle hasta40
movl $40, basico
subl $40, %eax
cmpl $20, %eax
jle hasta60
movl $20, medio
subl $20, %eax
movl %eax, doble
jmp seguir
movl %eax, basico
jmp seguir
movl %eax, medio
hasta40:
hasta60:
#
#
#
#
#
#
#
#
#
seguir:
califica:
califica2:
calcula:
#
#
#
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
230
pushl %edx
pushl $salida
call printf
Captulo 8
8.1# Programa que suma los elementos de un arreglo de n enteros
.section .data
lee:
.asciz"Introduzca el numero de elementos del arreglo: \n"
n:
.long 0
leenum:
.asciz"Introduzca a[ %d ]: \t"
leen:
.asciz"%d"
x:
.long 0
resul:
.asciz"La suma de los elementos del arreglo es:
%d\n"
.section .bss
arreglo:
.space 400
.section .text
.globl _start
_start:
pushl $lee
call printf
leal n, %eax
pushl %eax
pushl $leen
call scanf
xorl %esi, %esi
xorl %edi, %edi
leesum:
cmpl n, %esi
je fin
pushl %esi
pushl $leenum
call printf
leal x, %ebx
pushl %ebx
pushl $leen
call scanf
addl x, %edi
incl %esi
jmp leesum
fin:
pushl %edi
pushl $resul
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
#
#
#
#
lee a[i]
suma a[i] a %edi
incrementa %esi (i)
vuelve a leer siguiente elemento
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
231
8.2# Programa que calcula el promedio de los numeros de un arreglo de
# 20 enteros
.section .data
leenum:
.asciz"Introduzca a[ %d ]: \t"
leen:
.asciz"%d"
x:
.long 0
resul:
.asciz"El promedio de los elementos del arreglo es: %d\n"
.section .bss
arreglo:
.space 400
.section .text
.globl _start
_start:
leearr:
fin:
#
#
#
#
#
#
#
#
#
#
#
#
lee a[i]
suma a[i] en %edi
incrementa el indice (i)
vuelve a leer siguiente a[i]
%ebx=20 (tamano del arreglo)
%eax=suma de los elementos del arreglo
expande %eax
divide %eax/20
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
232
.section .text
.globl _start
_start:
pushl $lee
call printf
leal n, %eax
pushl %eax
pushl $leen
call scanf
xorl %esi, %esi
xorl %edi, %edi
leearr:
cmpl n, %esi
je fin
pushl %esi
pushl $leenum
call printf
leal x, %ebx
pushl %ebx
pushl $leen
call scanf
movl x, %eax
cltd
movl $2, %ecx
idivl %ecx
cmpl $0, %edx
jne nopar
incl %edi
nopar:
incl %esi
jmp leearr
fin:
pushl %edi
pushl $resul
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
# lee a[i]
#
#
#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
233
leearr:
nopar:
fin:
call printf
leal n, %eax
pushl %eax
pushl $leen
call scanf
xorl %esi, %esi
xorl %edi, %edi
cmpl n, %esi
je fin
pushl %esi
pushl $leenum
call printf
leal x, %ebx
pushl %ebx
pushl $leen
call scanf
movl x, %eax
cltd
movl $2, %ecx
idivl %ecx
cmpl $0, %edx
jne nopar
addl x,%edi
incl %esi
jmp leearr
pushl %edi
pushl $resul
call printf
movl $1, %eax
movl $0, %ebx
int $0x80
#
#
#
#
#
# lee a[i]
#
#
#
#
#
#
#
# imprime el ancabezado
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
234
# Leemos el arreglo
xorl %esi, %esi
# %esi es el indice (i)
leearr:
cmpl tamano, %esi
# compara indice con tamano (12)
je finlee
# si indice=12 salta a fin de lectura
pushl %esi
pushl $pidenum
call printf
# imprime mensaje para leer arreglo[i]
leal num, %ebx
pushl %ebx
pushl $leenum
call scanf
# lee arreglo[i]
movl num, %eax
# transfiere num a %eax temporalmente
movl %eax, arreglo(,%esi,4)
# guarda num en arreglo
incl %esi
# incrementa el indice (i)
jmp leearr
# vuelve a leer siguiente a[i]
# Ahora determinamos el mayor y su posicion, %eax va a contener el mayor y %ebx
la posicion
finlee:
xorl %esi, %esi
# Inicia el indice
movl arreglo(,%esi,4), %ecx
# lee primer num
movl %ecx, %eax
# lo guarda como mayor
movl %esi, %ebx
# guarda su posicion
incl %esi
# incrementa indice
leesig:
movl arreglo(,%esi,4), %ecx
# lee siguiente numero
cmpl %eax, %ecx
# compara nuevo num con mayor anterior
jle noreemplz
# si no es mayor va a noreemplz
movl %ecx, %eax
# si es mayor reemplaza num
movl %esi, %ebx
# y la posicion
noreemplz:
incl %esi
# incrementa el indice
cmpl tamano,%esi
# verifica fin del arreglo
je fincomp
# si indice igual a 12 termina
jmp leesig
# si indice menor que 12 lee siguiente
fincomp:
pushl %eax
# imprime el mayor
pushl $impmayor
call printf
pushl %ebx
# imprime la posicion
pushl $impposic
call printf
movl $1, %eax
# fin del programa
movl $0, %ebx
int $0x80
Captulo 9
9.1# Programa que calcula el promedio de los pares
.section .data
mensaje:
.asciz"Programa que lee un arreglo a de 20 enteros y calcula\n"
mensaj2:
.asciz"el promedio de los numeros pares presentes en el arreglo\n"
leernum:
.asciz"Introduzca a[%d]:\t"
entrada:
.asciz"%d"
salida:
.asciz"Hay %d numeros pares y su promedio es: %d\n"
salto:
.asciz"\n\n"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
235
num:
pares:
.long 0
.long 0, 0
.section .bss
a:
.space 80
.section .text
.globl _start
_start:
pushl $mensaje
# muestra mensaje inicial
call printf
pushl $mensaj2
call printf
xorl %esi, %esi
leearr:
cmpl $20, %esi
# ciclo que lee los elementos del arreglo
je finlee
pushl %esi
pushl $leernum
call printf
pushl $num
pushl $entrada
call scanf
movl num, %eax
movl %eax, a(,%esi,4)
incl %esi
jmp leearr
finlee:
pushl $a
pushl $pares
call par
#
#
#
#
pushl pares
leal pares, %eax
addl $4, %eax
movl (%eax), %ecx
pushl %ecx
pushl $salida
call printf
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
236
verifica:
finverif:
9.2# Programa que calcula la suma de los numeros mayores que 10 y menores que 100
presentes en un arreglo de enteros
.section .data
mensaje:
.asciz"Programa que lee un arreglo de n enteros y calcula\n"
mensaj2:
.asciz"la suma de los numeros entre 10 y 100\n"
leertam:
.asciz"Introduzca el numero de elementos del arreglo:\t"
entrada:
.asciz"%d"
leenum:
.asciz"Introduzca los valores del arreglo\n"
salida:
.asciz"La suma de los numeros entre 10 y 100 es: %d\n"
salto: .asciz"\n\n"
n:
num:
.long 0
.long 0
.section .bss
a:
.space 400
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $mensaj2
call printf
pushl $leertam
call printf
pushl $n
pushl $entrada
call scanf
pushl $salto
call printf
pushl $leenum
call printf
addl $24, %esp
# arreglo a
# mensaje inicial
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
237
leearr:
cmpl n, %esi
# ciclo que lee los valores del arreglo
je finlee
pushl $num
pushl $entrada
call scanf
addl $8, %esp
movl num, %eax
movl %eax, a(,%esi,4)
incl %esi
jmp leearr
finlee:
pushl $a
# dir inicial del arreglo
pushl n
# tamano del arreglo
call suma
# la funcion suma retorna la suma de
addl $8, %esp # los numeros entre 10 y 100
imprime:
pushl %eax
pushl $salida
call printf
9.3# Solucin 1:
# Programa que calcula el factorial de un nmero de manera iterativa
.section .rodata
CAD:
.asciz "Por favor indique un nmero: "
CADF: .asciz "%d"
CADR: .asciz "El factorial del nmero es: %d\n"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
238
.section .bss
NUM:
.space 4
.section .text
.globl _start
_start:
pushl $CAD
call printf
addl $4, %esp
# Pedimos el nmero
pushl $NUM
pushl $CADF
call scanf
addl $8, %esp
# Lo almacenamos en NUM
pushl NUM
call fact
addl $4, %esp
# Calculamos el factorial
pushl %eax
pushl $CADR
call printf
addl $8, %esp
# Mostramos el resultado
# Terminamos el programa
for:
# El factorial de 0 es 1
epilogo:
popl %edi
popl %esi
popl %ebx
leave
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
239
ret
# Solucin 2:
# Programa que calcula el factorial de un nmero de manera recursiva
.section .rodata
CAD:
.asciz "Por favor indique un nmero: "
CADF: .asciz "%d"
CADR: .asciz "El factorial del nmero es: %d\n"
.section .bss
NUM:
.space 4
.section .text
.globl _start
_start:
pushl $CAD
call printf
addl $4, %esp
# Pedimos el nmero
pushl $NUM
pushl $CADF
call scanf
addl $8, %esp
# Lo almacenamos en NUM
pushl NUM
call fact
addl $4, %esp
# Calculamos el factorial
pushl %eax
pushl $CADR
call printf
addl $8, %esp
# Mostramos el resultado
# Terminamos el programa
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
240
movl 8(%ebp), %edx
decl %edx
pushl %edx
call fact
addl $4, %esp
imull 8(%ebp)
jmp epilogo
base:
epilogo:
popl %edi
popl %esi
popl %ebx
leave
ret
.long 0
.section .bss
arrfib:
.space 400
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $leern
call printf
pushl $n
pushl $entrada
call scanf
mayor0:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
241
call fib
# llama a fib para generar la serie
addl $8, %esp
pushl n
pushl $salida
call printf
# muestra mensaje de salida
addl $8, %esp
xorl %edi, %edi
movl n, %esi
cmpl %esi, %edi
# compara indice con n
je fin
movl arrfib(,%edi,4), %eax
incl %edi
pushl %eax
# muestra la serie por pantalla
pushl $salid2
call printf
addl $8, %esp
jmp serie
pushl $salto
# imprime un salto de linea
call printf
movl $1, %eax
# fin del programa
xorl %ebx, %ebx
int $0x80
serie:
fin:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %ebx
xorl %ecx, %ecx
movl $1, (%edx, %ecx, 4)
cmpl $1, %ebx
je finfib
incl %ecx
movl $1, (%edx, %ecx, 4)
incl %ecx
movl $1, %edi
movl $1, %esi
cmpl %ebx, %ecx
je finfib
movl %edi, %eax
addl %esi, %eax
movl %eax, (%edx, %ecx, 4)
incl %ecx
movl %esi, %edi
movl %eax, %esi
jmp ciclo
leave
ret
ciclo:
finfib:
#
#
#
#
%edx=dir arreglo
%ebx=n (n>0)
%ecx=0 indice del arreglo
arrfib[0]=1
#
#
#
#
#
Capitulo 10
10.1.# Este programa solicita al usuario una contrasena y la compara
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
242
# con la cadena de caracteres declarada en la seccion de datos,
# indica si la contrasena es valida o no
.section .data
contras:
.asciz"clave1234"
largo:
.long 9
escriba:
.asciz"Por favor introduzca la contrasena: "
format1:
.asciz"%s"
resultig:
.asciz"La contrasena es correcta\n"
resultno:
.asciz"La contrasena es incorrecta\n"
.section .bss
clave:
.space 9
.section .text
.globl _start
_start:
pushl $escriba
call printf
addl $8, %esp
leal clave, %edx
pushl %edx
pushl $format1
call scanf
cld
leal contras, %edi
leal clave, %esi
movl largo, %ecx
repe cmpsb
jne error
pushl $resultig
call printf
jmp fin
error: pushl $resultno
call printf
fin:
movl $1, %eax
movl $0, %ebx
int $0x80
# limpia la bandera DF
# actualiza %edi con inicio de la contrasena
# actualiza %esi con inicio de la clave leida
# actualiza %ecx con el numero de caracteres
# compara 1 caracter a la vez
# si es incorrecta va a error
# si es correcta imprime el mensaje correspondiente
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
243
cadena:
.space 100
.section .text
.globl _start
_start:
pushl $mensaj1
call printf
pushl $escriba
call printf
addl $8, %esp
leal cadena, %edx
pushl %edx
pushl $format1
call scanf
# lee la cadena
cld
# limpia la bandera DF
leal cadena, %edi
# actualiza %edi con inicio de la cadena leida
# determinar el tamano de la cadena leida
movl $100, %ecx
movb $0, %al
repne scasb
jne fin
# caso de excepcion
subl $100, %ecx
neg %ecx
decl %ecx
movl %ecx, largo
# comparar la cadena leida con el caracter
leal cadena, %edi
leal caracter, %esi
# actualiza %esi con el inicio del caracter
lodsb
repne scasb
jne noesta
subl largo, %ecx
neg %ecx
pushl %ecx
pushl $salida2
call printf
jmp fin
noesta:
pushl $salida1
call printf
fin:
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
244
salida:
cadena\n"
.asciz"El caracter
.section .bss
cadena:
.space 100
.section .text
.globl _start
_start:
pushl $mensaj1
call printf
pushl $leecad
call printf
addl $8, %esp
leal cadena, %edx
pushl %edx
pushl $format1
call scanf
addl $8, %esp
cld
# calcula largo de la cadena
leal cadena, %edi
movl $100, %ecx
movb $0, %al
repne scasb
jne fin
subl $100, %ecx
neg %ecx
decl %ecx
xorl %ebx, %ebx
leal cadena, %edi
leal y, %esi
lodsb
revisa:
repne scasb
jne termina
incl %ebx
jmp revisa
termina:
pushl %ebx
pushl $salida
call printf
fin:
'y'
# lee la cadena
# caso de excepcion
# carga y en %al
Capitulo 11
11.1.# Programa que calcula la nota
.section .data
mensaje: .asciz"Programa que calcula la nota definitiva, teniendo como entrada 6
notas parciales.\n"
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
245
mensaje2:
.asciz"Muestra la nota final con decimales y la definitiva
redondeada\n"
entrada1:
.asciz"Introduzca las notas:\n"
nota1:
.asciz"Nota 1 (valor: 20%): "
nota2:
.asciz"Nota 2 (valor: 15%): "
nota3:
.asciz"Nota 3 (valor: 25%): "
nota4:
.asciz"Nota 4 (valor: 10%): "
nota5:
.asciz"Nota 5 (valor: 25%): "
nota6:
.asciz"Nota 6 (valor: 5%): "
leenota: .asciz"%d"
salto:
.asciz"\n"
n1:
.long 0
n2:
.long 0
n3:
.long 0
n4:
.long 0
n5:
.long 0
n6:
.long 0
porc20:
.float .20
porc15:
.float .15
porc25:
.float .25
porc10:
.float .10
porc5:
.float .05
result2: .quad 0
forma1:
.asciz"Nota final: %.2f\n"
# formato de salida con dos
# decimales
forma2:
.asciz"Nota definitiva: %d\n" # formato de salida entero
redondeo:
.byte 0x7f, 0x0b
# para actualizar el
# redondeo hacia arriba
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $mensaje2
call printf
pushl $salto
call printf
pushl $entrada1
call printf
addl $16, %esp
# mensaje inicial
pushl $nota1
call printf
pushl $n1
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
# lee nota 1
pushl $nota2
call printf
# lee nota 2
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
246
pushl $n2
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
pushl $nota3
call printf
pushl $n3
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
# lee nota 3
pushl $nota4
call printf
pushl $n4
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
lee nota 4
pushl $nota5
call printf
pushl $n5
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
lee nota 5
pushl $nota6
call printf
pushl $n6
pushl $leenota
call scanf
pushl $salto
call printf
addl $16, %esp
# lee nota 6
finit
fldcw
filds
fmuls
filds
fmuls
filds
fmuls
filds
fmuls
redondeo
n1
porc20
n2
porc15
n3
porc25
n4
porc10
#
#
#
#
#
#
#
#
# inicializa FPU
# cambia a redondeo hacia arriba
carga nota 1
multiplica nota 1 * 20%
carga nota 2
multiplica nota 2 * 15%
carga nota 3
multiplica nota 3 * 25%
carga nota 4
multiplica nota 4 * 10%
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
247
filds
fmuls
filds
fmuls
faddp
faddp
faddp
faddp
faddp
n5
porc25
n6
porc5
# carga nota 5
# multiplica nota 5 * 25%
# carga nota 6
# multiplica nota 6 * 5%
# suma los valores de las notas
fistl result2
# guarda el resultado
pushl result2
pushl $forma2
call printf
addl $8, %esp
11.2..section .data
mensaje: .asciz"Programa que convierte grados Centigrados a Fahrenheit\n"
introd:
.asciz"Introduzca los grados Centigrados: "
leegrado:
.asciz"%f"
salto:
.asciz"\n"
grados:
.float 0.0
nueve:
.float 9.0
cinco:
.float 5.0
treinta2:
.float 32.0
salida:
.asciz"Grados Fahrenheit= %.2f\n"
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $introd
call printf
addl $8, %esp
pushl $grados
pushl $leegrado
call scanf
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
248
pushl $salto
call printf
finit
flds grados
fdivs cinco
fmuls nueve
fadds treinta2
subl $8, %esp
fstpl (%esp)
pushl $salida
call printf
movl $1, %eax
xorl %ebx, %ebx
int $0x80
11.3..section .data
mensaje: .asciz"Programa que calcula el promedio de temperatura\n"
mensaje2:
.asciz"dados 10 valores en grados Centigrados\n"
pidevalor:
.asciz"Introduzca el valor %d: "
leegrado:
salto:
grado:
cero:
diez:
salida:
.asciz"%f"
.asciz"\n"
.float 0.0
.float 0.0
.float 10.0
.asciz"El promedio de temperatura es: %.4f\n"
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $mensaje2
call printf
addl $8, %esp
leeysuma:
finit
flds cero
xorl %edi, %edi
incl %edi
cmpl $10, %edi
jg termina
pushl %edi
pushl $pidevalor
call printf
addl $8, %esp
incl %edi
pushl $grado
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
249
pushl $leegrado
call scanf
addl $8, %esp
fadds grado
jmp leeysuma
termina: fdivs diez
subl $8, %esp
fstpl (%esp)
pushl $salida
call printf
movl $1, %eax
xorl %ebx, %ebx
int $0x80
11.4..section
mensaje:
introd:
leediam:
salto:
diam:
dos:
salida:
.data
.asciz"Programa que calcula el area de un circulo dado su diametro\n"
.asciz"Introduzca el diametro: "
.asciz"%f"
.asciz"\n"
.float 0.0
.float 2.0
.asciz"Area del circulo= %.4f\n"
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $introd
call printf
addl $8, %esp
pushl $diam
pushl $leediam
call scanf
pushl $salto
call printf
finit
flds diam
fdivs dos
fst %st(1)
fmul %st(1), %st(0)
fldpi
fmul %st(1), %st(0)
# apila diametro
# divide diam/2
# apila pi
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
250
subl $8, %esp
fstpl (%esp)
pushl $salida
call printf
movl $1, %eax
xorl %ebx, %ebx
int $0x80
11.5..section .data
mensaje: .asciz"Programa que convierte kilometros en millas o millas en
kilometros\n"
tipoconv:
.asciz"Indique el tipo de conversion que desea realizar:\n"
tipo1:
.asciz"Convertir de kilometros a millas [k] o de millas a
kilometros [m]: "
leetipo: .asciz"%c"
salto:
.asciz"\n"
kiloms:
.asciz"Introduzca la cantidad de kilometros: "
millas:
.asciz"Introduzca la cantidad de millas: "
formatof:
.asciz"%f"
km:
.float 0.0
milla:
.float 0.0
convers: .float 0.62
kmmilla: .asciz"Son %.2f millas\n"
millakm: .asciz"Son %.2f kilometros\n"
.section .bss
tipo:
.space 1
.section .text
.globl _start
_start:
pushl $mensaje
call printf
pushl $tipoconv
call printf
pidetipo:
pushl $tipo1
call printf
addl $12, %esp
pushl $tipo
pushl $leetipo
call scanf
addl $8, %esp
cmpl $'k', tipo
je kilo
cmpl $'K', tipo
je kilo
cmpl $'m', tipo
je mill
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
251
cmpl $'M', tipo
je mill
jmp pidetipo
pushl $salto
call printf
addl $4, %esp
finit
kilo:
pushl $kiloms
call printf
addl $4, %esp
pushl $km
pushl $formatof
call scanf
addl $8, %esp
flds km
fmuls convers
subl $8, %esp
fstpl (%esp)
pushl $kmmilla
call printf
jmp fin
mill:
pushl $millas
call printf
addl $4, %esp
pushl $milla
pushl $formatof
call scanf
addl $8, %esp
flds milla
fdivs convers
subl $8, %esp
fstpl (%esp)
pushl $millakm
call printf
fin:
Capitulo 12
12.1.# Utilice el siguiente script para desactivar el buffering y echo del terminal
# more.sh:
# stty -icanon -echo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
252
# ./12-1 $1
# stty icanon echo
.section
cad:
formato:
modor:
.rodata
.asciz "Ocurri un error al intentar abrir el archivo especificado\n"
.asciz "%s"
.asciz "r"
.section
fd:
buffer:
char:
.bss
.space 4
.space 80
.space 1
.section .text
.globl _start
_start:
movl 8(%esp), %eax
# lineas = 0
rep:
# Lee una linea del archivo
pushl fd
# Apuntador al archivo abierto
pushl $80
# Cantidad de caracteres a leer (mximo)
pushl $buffer
# Apuntador al buffer
call fgets
# Llama a fscanf
addl $12, %esp
# Se muestra por la pantalla
pushl $buffer
# Apuntador al buffer
pushl $formato
# Cadena de formato
call printf
addl $8, %esp
# Si se alcanz el final del archivo sale del ciclo
pushl fd
# Apuntador al archivo abierto
call feof
# Llama a feof
addl $4, %esp
cmpl $0, %eax
# Si se alcanz el final del archivo
jne fin
# Termina el programa
incl %edi
cmpl $25,%edi
# lineas = lineas + 1
# Si se han mostrado 25 lineas
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
253
je espera
jmp rep
espera:
call getchar
movb %al, char
cmpb $'\n', char
je avanzar1
cmpb $' ', char
je avanzar25
jmp espera
#
#
#
#
Si pis ENTER
Avanza una lnea
Si pis la barra espaciadora
Avanza una pgina (25 lneas)
avanzar1:
decl %edi
jmp rep
# lineas = lineas - 1
avanzar25:
xorl %edi, %edi
jmp rep
# lineas = 0
error:
pushl $cad
call printf
addl $4, %esp
jmp fin2
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
12.2.#
#
#
#
#
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
254
.section
cad:
formato:
modor:
.rodata
.asciz "Ocurri un error al intentar abrir el archivo especificado\n"
.asciz "%s"
.asciz "r"
.section
fd:
buffer:
char:
.bss
.space 4
.space 80
.space 1
.section .text
.globl _start
_start:
# Abre el archivo en modo lectura
movl $5, %eax
# Servicio #5 (open)
movl 8(%esp), %ebx
# Ruta del archivo a abrir
movl $0, %ecx
# ORDONLY : 0
int $0x80
# Llamada al SO
mov %eax, fd
# Apuntador al archivo abierto
cmpl $0, fd
jl error
# lineas = 0
rep:
# Lee una linea del archivo
xorl %esi, %esi
leer:
movl $3, %eax
#
movl fd, %ebx
#
leal buffer(%esi), %ecx
#
movl $1, %edx
#
int $0x80
#
#
#
#
#
incl %esi
jmp leer
# lineas = lineas + 1
mostrar:
movb $0,buffer+1(%esi)
# lineas = lineas + 1
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
255
cmpl $25,%edi
je espera
jmp rep
espera:
call getchar
movb %al, char
cmpb $'\n', char
je avanzar1
cmpb $' ', char
je avanzar25
jmp espera
#
#
#
#
Si pis ENTER
Avanza una linea
Si pis la barra espaciadora
Avanza una pgina (25 lneas)
avanzar1:
decl %edi
jmp rep
# lineas = lineas - 1
avanzar25:
xorl %edi, %edi
jmp rep
# lineas = 0
error:
pushl $cad
call printf
addl $4, %esp
jmp fin2
# Servicio #6 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
12.3..section
cad1:
cad2:
cad3:
cad4:
cad5:
.rodata
.asciz "1 Insertar contacto\n2 Buscar contacto\n3 Eliminar contacto\n"
.asciz "Su opcin: "
.asciz "Ocurri un error al intentar abrir el archivo\n"
.asciz "Nombre del contacto: "
.asciz "Telfono del contacto: "
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
256
cad6:
cad7:
cad8:
cad9:
file:
file2:
format1:
format2:
format3:
modo1:
modo2:
modo3:
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
.asciz
"Posicin: "
"Nombre: %s\nTelefono: %d\n"
"La posicin indicada est vaca\n"
"Ocurri un error al intentar abrir el archivo temporal\n"
"agenda.txt"
"agenda.tmp"
"%d"
"%s"
"%s | %d\n"
"a"
"r"
"w"
.section
nombre:
tlf:
opcion:
pos:
desp:
fd:
fd2:
.bss
.space
.space
.space
.space
.space
.space
.space
80
4
4
4
4
4
4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
while:
pushl $cad2
call printf
addl $4, %esp
pushl $opcion
pushl $format1
call scanf
addl $8, %esp
# Si es 1 salta a insertar
# Si es 2 salta a buscar
# Si es 3 salta a eliminar
# En otro caso pregunta de nuevo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
257
pushl $file
call fopen
addl $8, %esp
# Archivo: agenda.txt
# Llama a fopen
mov %eax, fd
cmpl $0, fd
je error
pushl $cad4
call printf
addl $4, %esp
pushl $nombre
pushl $format2
call scanf
addl $8, %esp
pushl $cad5
call printf
addl $4, %esp
pushl $tlf
pushl $format1
call scanf
addl $8, %esp
#
#
#
#
#
Telefono
&Nombre
Cadena de formato
Apuntador al archivo abierto
Llama a fprintf
jmp fin
cmpl $0, fd
je error
pushl $cad6
call printf
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
258
addl $4, %esp
pushl $pos
pushl $format1
call scanf
addl $8, %esp
# i=0
# Si i=pos
# Salta a mostrar
rep:
# i++
# Repite la bsqueda
# Modo: w
# Archivo: agenda.tmp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
259
call fopen
addl $8, %esp
mov %eax, fd2
cmpl $0, fd2
je error2
# Llama a fopen
pushl $cad6
call printf
addl $4, %esp
pushl $pos
pushl $format1
call scanf
addl $8, %esp
# Si i=pos
# No copia el contacto
# i++
fcopiar:
# Cierra ambos archivos
pushl fd
call fclose
addl $4, %esp
pushl fd2
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
260
call fclose
addl $4, %esp
# Llama a fclose
fin:
# Cierra el archivo si estaba abierto
pushl fd
# Descriptor del archivo a cerrar
call fclose
# Llama a fclose
addl $4, %esp
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
12.4.-
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
261
.section .rodata
cad1:
.asciz "1 Insertar contacto\n2 Buscar contacto\n3 Eliminar contacto\n"
cad2:
.asciz "Su opcin: "
cad3:
.asciz "Ocurri un error al intentar abrir el archivo\n"
cad4:
.asciz "Nombre del contacto: "
cad5:
.asciz "Telfono del contacto: "
cad6:
.asciz "Posicin: "
cad7:
.asciz "Nombre: %s\nTelefono: %d\n"
cad8:
.asciz "La posicin indicada est vaca\n"
cad9:
.asciz "Ocurri un error al intentar abrir el archivo temporal\n"
file:
.asciz "agenda3.dat"
file2:
.asciz "agenda3.tmp"
format1:.asciz "%d"
format2:.asciz "%s"
.section .bss
nombre: .space 80
tlf: .space 4
opcion: .space 4
pos: .space 4
desp:
.space 4
fd: .space 4
fd2: .space 4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
while:
pushl $cad2
call printf
addl $4, %esp
pushl $opcion
pushl $format1
call scanf
addl $8, %esp
# Si es 1 salta a insertar
# Si es 2 salta a buscar
# Si es 3 salta a eliminar
# En otro caso pregunta de nuevo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
262
insertar:
movl $5, %eax
movl $file, %ebx
movl $02101, %ecx
movl $0644, %edx
int $0x80
mov %eax, fd
#
#
#
#
#
#
Servicio #5 (open)
Ruta del archivo a abrir
O_CREAT | O_APPEND | O_WRONLY
Permisos del archivo
Llamada al SO
Apuntador al archivo abierto
cmpl $0, fd
jl error
pushl $cad4
call printf
addl $4, %esp
pushl $nombre
pushl $format2
call scanf
addl $8, %esp
pushl $cad5
call printf
addl $4, %esp
pushl $tlf
pushl $format1
call scanf
addl $8, %esp
pushl $cad6
call printf
addl $4, %esp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
263
pushl $pos
pushl $format1
call scanf
addl $8, %esp
decl pos
movl $84, %eax
imull pos
movl %eax, desp
# desplazamiento = (posicin-1)*84
pushl tlf
pushl $nombre
pushl $cad7
call printf
addl $12, %esp
jmp fin
#
#
#
#
#
#
Servicio #5 (open)
Ruta del archivo a abrir
O_CREAT | O_APPEND | O_WRONLY
Permisos del archivo
Llamada al SO
Apuntador al archivo abierto
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
264
cmpl $0, fd2
jl error2
pushl $cad6
call printf
addl $4, %esp
pushl $pos
pushl $format1
call scanf
addl $8, %esp
# Si i=pos
# No copia el contacto
# i++
# Servicio #6 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Servicio #6 (close)
# File Descriptor del archivo abierto
# Llamada al SO
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
265
fin:
# Cierra el archivo si estaba abierto
movl $6, %eax
# Servicio #6 (close)
movl fd, %ebx
# File Descriptor del archivo abierto
int $0x80
# Llamada al SO
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
12.5..section
cad1:
cad2:
cad3:
cad4:
cad5:
cad6:
.rodata
.asciz "Archivo
.asciz "Archivo
.asciz "Archivo
.asciz "Ocurri
.asciz "Ocurri
.asciz "Ocurri
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
266
formato:.asciz "%s"
char:
.asciz "%c"
modor:
.asciz "r"
modow:
.asciz "w"
.section .bss
fuente1:.space 80
fuente2:.space 80
destino:.space 80
fd1: .space 4
fd2: .space 4
fd3: .space 4
buffer: .space 1
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
pushl $fuente1
pushl $formato
call scanf
addl $8, %esp
pushl $cad2
call printf
addl $4, %esp
pushl $fuente2
pushl $formato
call scanf
addl $8, %esp
pushl $cad3
call printf
addl $4, %esp
pushl $destino
pushl $formato
call scanf
addl $8, %esp
# Abre los dos archivos fuentes para lectura y el destino para escritura
pushl $modor
pushl $fuente1
call fopen
addl $8, %esp
# Modo: r
# Archivo fuente 1
# Llama a fopen
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
267
mov %eax, fd1
pushl $modor
pushl $fuente2
call fopen
addl $8, %esp
mov %eax, fd2
# Modo: r
# Archivo fuente 2
# Llama a fopen
pushl $modow
pushl $destino
call fopen
addl $8, %esp
mov %eax, fd3
# Modo: w
# Archivo destino
# Llama a fopen
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
268
call fscanf
addl $8, %esp
# Llama a fscanf
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
269
addl $4, %esp
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
12.6..section
cad1:
cad2:
cad3:
cad4:
cad5:
cad6:
formato:
char:
modor:
modow:
.rodata
.asciz "Archivo
.asciz "Archivo
.asciz "Archivo
.asciz "Ocurri
.asciz "Ocurri
.asciz "Ocurri
.asciz "%s"
.asciz "%c"
.asciz "r"
.asciz "w"
.section .bss
fuente1: .space 80
fuente2: .space 80
destino: .space 80
fd1:
.space 4
fd2:
.space 4
fd3:
.space 4
buffer: .space 84*500
contactos:.space 4
.section .text
.globl _start
_start:
pushl $cad1
call printf
addl $4, %esp
pushl $fuente1
pushl $formato
call scanf
addl $8, %esp
pushl $cad2
call printf
addl $4, %esp
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
270
pushl $fuente2
pushl $formato
call scanf
addl $8, %esp
pushl $cad3
call printf
addl $4, %esp
pushl $destino
pushl $formato
call scanf
addl $8, %esp
# Abre los dos archivos fuentes para lectura y el destino para escritura
movl $5, %eax
movl $fuente1, %ebx
movl $0, %ecx
int $0x80
mov %eax, fd1
cmpl $0, fd1
jl error1
#
#
#
#
#
#
Servicio #5 (open)
Ruta del archivo a abrir
ORDONLY : 0
Llamada al SO
Apuntador al archivo abierto
Si fd<0 ocurri un error
#
#
#
#
#
#
Servicio #5 (open)
Ruta del archivo a abrir
ORDONLY : 0
Llamada al SO
Apuntador al archivo abierto
Si fd<0 ocurri un error
#
#
#
#
#
#
#
Servicio #5 (open)
Ruta del archivo a abrir
O_CREAT | O_TRUNC | O_WRONLY
Permisos del archivo
Llamada al SO
Apuntador al archivo abierto
Si fd<0 ocurri un error
# contactos = 0
# Servicio #3, (read)
# File Descriptor del archivo abierto
# Direccin donde se almacenarn los datos
# Nmero de bytes a leer
# Llamada al SO
# Si se leyeron cero bytes
# Termin con este archivo
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
271
jmp copiar1
copiar2:
movl $3, %eax
movl fd2, %ebx
leal buffer, %ecx
addl contactos,%ecx
movl $84, %edx
int $0x80
cmpl $0, %eax
je seguir
xorl %ebx, %ebx
revisar:cmpl contactos,%ebx
jge noesta
leal buffer(%ebx), %esi
leal buffer, %edi
addl contactos, %edi
movl $80, %ecx
rep cmpsb
je copiar2
addl $84, %ebx
jmp revisar
noesta:
addl $84,contactos
jmp copiar2
seguir:
xorl %edi, %edi
vaciar: cmpl contactos, %edi
jge fin
movl $4, %eax
movl fd3, %ebx
leal buffer(%edi), %ecx
movl $84, %edx
int $0x80
addl $84, %edi
jmp vaciar
# i=0
# mientras i<contactos
#
#
#
#
#
error1:
pushl $cad4
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.
272
call printf
addl $4, %esp
jmp fin
fin: # Cierra cualquier archivo abierto previamente
cierra1:cmpl $0, fd1
jl cierra2
movl $6, %eax
movl fd1, %ebx
int $0x80
# Servicio #5 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Servicio #5 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Servicio #5 (close)
# File Descriptor del archivo abierto
# Llamada al SO
# Termina el programa
fin2:
movl $1, %eax
movl $0, %ebx
int $0x80
Este documento es propiedad intelectual de los autores, Amelia Ferreira y Vicente Robles.
Su reproduccin total o parcial requiere la autorizacin previa de sus autores. Caracas 2007.