SlideShare una empresa de Scribd logo
1 de 66
Descargar para leer sin conexión
Lenguaje Ensamblador: Guia práctica...............................................................................................2
¿QUÉ NECESITO? ...............................................................................................................................2
¿QUÉ HAGO CON TODOS LOS RECURSOS QUE NECESITO? ..............................................................3
¡A PROGRAMAR! ...............................................................................................................................7
1. Hola mundo ...............................................................................................................................7
2. Plantilla básica.........................................................................................................................10
3. Ensamblando y enlazando con C: ejemplo mcd......................................................................12
4. Generando números aleatorios...............................................................................................16
5. Encontrando números primos.................................................................................................19
6. Manipulación de bits: desplazando y alternando...................................................................33
7. Operaciones booleanas: and, or, xor, not...............................................................................48
8. Elección sin árbol: escoger número más grande.....................................................................54
9. Arreglos: definiendo y manejando direcciones.......................................................................57
10. Punto flotante: ejemplo ecuación cuadrática.......................................................................61
FUENTES ANEXAS: ...........................................................................................................................65
Página 2 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Lenguaje Ensamblador: Guia práctica
Jesús Antonio Ferrer Sánchez
Para programar en lenguaje ensamblador escogí la especificación NASM (Netwide Assembler) que
soporta las plataformas Windows y Unix (Linux), dejando aparte las que son conocidas por defecto
para cada sistema operativo (MASM para Windows, TSAM para Mac y GAS para Linux). Seguro
piensan ¿Cuál es la razón? La respuesta es que el propio nombre lo dice “Netwide Assembler”, es
decir, existe una comunidad que mantiene actualizada documentación y herramientas para
programar en lenguaje ensamblador.
Bueno… manos a la obra, para empezar necesitamos visitar el sitio Web donde se encuentra los más
importante que necesitaremos http://www.nasm.us/, hecho esto la siguiente cuestión es ¿Qué
vamos a utilizar de allí? Pues lo siguiente:
¿QUÉ NECESITO?
1. La documentación, que está aquí:
http://www.nasm.us/docs.php aunque realmente existe documentación más actualizada como en
su sitio de Sourceforge o Git, por ejemplo. Lo más recomendable es utilizar la versión estable.
2. El compilador e intérprete, que está aquí:
http://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D estando allí debemos abrir la primera
carpeta de arriba hacia abajo que no contenga la terminación rc, por ejemplo abriremos la carpeta
2.11.05 (fijate que no dice 2.11.05rc) estando dentro bajaremos el compilador e intérprete de
acuerdo a nuestro tipo sistema operativo especifico, que se identifican con los nombre de las
carpeta linux/, macosx/ y win32/ para los usuario Windows x64 no se espanten porque dice win32
pueden lograr mayor compatibilidad con DOSBox (http://www.dosbox.com/). Ahora hago una
distinción para Windows y Linux (para Mac no, porque soy super pobre).
2.1. Para los usuarios Windows recomiendo que descarguen el instalador (nasm-2.11.05-
installer.exe, por ejemplo) esto para su mayor comodidad.
2.2. Para los usuarios Linux no es necesario entrar a la carpeta linux/ puesto que lo
recomendable es trabajar con el archivo que se identifica con la terminación .tar.gz (nasm-
2.11.05.tar.gz, por ejemplo) ya verán porque más adelantito.
3. El enlazador para Windows OS (para Linux no es necesario):
UNIVERSIDAD JUÁREZ AUTÓNOMA DE TABASCO
DIVISIÓN ACADÉMICA DE INFORMÁTICA Y SISTEMAS
Página 3 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Necesitamos solamente Alink el cual trabaja en conjunto con Nasm para la plataforma Windows,
este es un complemento totalmente necesario. Para descargarlo debemos ir a:
http://alink.sourceforge.net/download.html estando aquí seleccionar Download ALINK (Win32
version) el cual deberá mandarnos un archivo nombrado al_al.zip
4. Un editor en consola:
Ya sea Vi, Vim o nano, para mi comodidad elegí nano porque viene por defecto en Linux y funciona
igualito en Windows, ya saben para conseguirlo ir a:
http://www.nano-editor.org/ para conseguirlo para Windows navegar hasta: http://www.nano-
editor.org/dist/v2.2/NT/nano-2.2.6.zip y listo habremos descargado nano para Windows. Esto lo
hago para no perder la costumbre de usar la línea de comandos.
Ahora la siguiente cuestión es ¿Qué hago con todo esto… para empezar a volar programando en
Lenguaje ensamblador? Pues lo siguiente:
¿QUÉ HAGO CON TODOS LOS RECURSOS QUE NECESITO?
Aquí hago distinción sobre qué hacer, primero en Windows y acto seguido en Linux, como sigue:
En Windows:
1. Ejecutamos el instalador (nasm-2.11.05-installer.exe, por ejemplo). Dejamos que se instale todo
por defecto. Por ejemplo, dejen que sea creado un acceso directo en el escritorio ya que nos va
ahorrar esfuerzo para hacer algo que explicare a continuación.
2. Una vez que está instalado recurrimos al acceso directo que había comentado o vamos a su
carpeta respectiva carpeta en el menú de inicio. Lo que vamos a hacer aquí es que por medio de la
opción Abrir la ubicación del archivo vamos a ubicarnos donde se encuentran todos los recursos de
instalación. Esta carpeta la mantendremos abierta nos será útil unos pasos más adelante.
Página 4 de 66
Materia: Lenguaje Ensamblador Clave: F1265
3. Se supone que todavía tenemos abierta la carpeta donde está instalado NASM, bueno lo siguiente
es extraer allí el archivo al_al.zip que yo nombré alinker.zip los archivos tal y como se muestran NO
deben ser extraídos en una carpeta dentro de la carpeta ..AppDataLocalnasm deben estar en la
misma jerarquía.
4. Lo siguiente es copiar la ruta de instalación y agregarla a PATH en las variables de entorno de
Windows. Ustedes ya saben cómo, nos quedaría más o menos así:
5. El paso 4 o punto cuatro es para ahorranos chamba y que nasm sea accesible desde cualquier
parte de nuestro sistema operativo Windows. Lo que vamos a hacer ahora es que nasm y alinker se
casen para ello haremos lo siguiente:
5.1. Escribir desde la consola (CMD) lo siguiente alink y le daremos Enter a todo (--Press
Enter to continue--)
Página 5 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Después de esto nos mandará fuera de ejecución de alink. Lo que sigue aquí mismo es
verificar que se conserva la armonía con el depurador nativo de Windows para lo que
escribiremos debug y después r damos Enter y luego salimos escribiendo q habiendo
obtenido el stock de registros. La imagen siguiente muestra lo que comente.
Nota: Para quienes trabajen con Windows x64 pueden con el DOSBox (antes mencionado)
para ello pueden hay video donde explican acerca de él. Enlace exacto:
https://www.youtube.com/watch?v=pMrh-ppGp1E además necesitarán el archivo
debug.exe el cual lo subí a GoogleDrive junto con MASM en el siguiente enlace:
https://drive.google.com/file/d/0BxC4ezWP4GyIeFp1T3pRanVQVFk/view?usp=sharing y
como ya saben, usarlo con variables de entorno.
6. Ahora lo que hago es por pura vanidad, vamos con el archivo comprimido que descargamos que
contiene al editor nano (nano-editor_2.2.6.zip) lo extraemos en una ubicación acorde a nuestro
gusto (C:nano_2.2.6, por ejemplo) y lo agregamos a las variables de entorno.
Y listo ya tenemos todo listo para empezar con nasm desde Windows.
Página 6 de 66
Materia: Lenguaje Ensamblador Clave: F1265
En Linux:
1. Para instalar NASM en Linux hay dos vías una es por vía repositorio escribiendo sudo apt-get
install nasm lo cual nos instalará una versión sumamente antigua y la otra es por medio de la
compilación del archivo que descargamos (nasm-2.11.05.tar.gz). Si elegimos esta última debemos
hacer lo siguiente.
1.1. Extraer el archivo en un directorio con privilegios root en /usr/local/src por ejemplo
debemos conseguir que se nos cree la carpeta respectiva nasm-2.11.05 en mi caso, por
ejemplo. Luego nos ubicaremos dentro de dicha carpeta.
1.2. Lo que sigue es abrir la terminal y navegar hasta la carpeta que tenemos abierta. Luego
escribiremos sudo ./configure para ejecutar este script de unos 190 kb esperaremos
mientras se lleva a cabo el proceso una vez terminado tipeamos make para que se compilen
los archivos binarios de nasm, volvemos a esperar y ahora si a instalarlo con make install
que por defecto manda la instalación a /usr/local/bin luego comprobamos que
efectivamente tenemos instalado nasm como se ilustra en la siguiente imagen.
Debo mencionar que las ubicaciones simbólicas indican que en nuestro sistema instalo
correctamente a nasm.
Página 7 de 66
Materia: Lenguaje Ensamblador Clave: F1265
1.3. Tenemos la opción de agregar herramientas que complementan a nasm para ello
estando en /usr/local/src/nasm-2.11.05/rdoff desde terminal escribimos make rdf y luego
make rdf_install
1.4 Por ultimo eliminamos los archivos archivos de nasm de la ubicación /usr/local/src/ pues
ya no los necesitamos.
Y listo ya tenemos todo listo para empezar con NASM desde Linux. Al parecer fue más rollo para
Windows, disculpen...
¡A PROGRAMAR!
Para saber cómo trabajar con nasm consulte la documentación donde antes mencione, ya sea en
html o pdf.
Para estudiar los fundamentos hay 3 fuentes que recomiendo:
1. Abre los Ojos al Ensamblador: http://www.abreojosensamblador.net/Productos/AOE/Index.html
2. Assembly in youtube: https://www.youtube.com/playlist?list=PL001102C2DF1D0CE9
3. Intel® 64 and IA-32 Architectures Software:
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-
manuals.html
1. Hola mundo
La finalidad de este primer programa es seguir la tradición y para explicar la manera de trabajar que
consiste en editar un archivo .asm y compilarlo con nasm. Veamos cómo se hace:
En Windows:
Editamos nuestro archivo holawindows.asm desde nano. Una vez editado guardamos y nos
volvemos a ubicar desde consola en el directorio desde el cual estamos trabajando con el código.
Página 8 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Para compilarlo escribimos nasm holawindows.asm -o holawindows.[com, exe] en muestro caso
exe con la instrucción de salida de nasm (-o). Después damos Enter, revisamos que efectivamente
ha sido creado y lo mandamos a ejecutar escribiendo el nombre del archivo sin extensión para
comprobar. Lo mismo pasaría si decidiéramos generar un ejecutable .com sólo que lo ejecutaríamos
con un tercer archivo que es generado por el propio nasm.
En Linux:
Primero nos aseguramos que el directorio en el que vamos a trabajar esta con propiedades de
lectura, escritura y ejecución (chmod 777). Entonces editamos nuestro archivo holalinux.asm desde
nano. Una vez editado guardamos y nos volvemos a ubicar desde terminal en el directorio desde el
cual estamos trabajando con el código.
Para enlazar escribimos nasm -f elf holalinux.asm damos Enter y para ensamblar escribimos ld -s -
o holalinux holalinux.o donde primero nos creará el script de ejecución y luego el archivo objeto
binario. Después damos Enter, revisamos que efectivamente 2 archivos han sido creados y lo
mandamos a ejecutar escribiendo ./holalinux el nombre del archivo sin extensión para comprobar.
Página 9 de 66
Materia: Lenguaje Ensamblador Clave: F1265
CÓDIGO:
holawindows.asm
org 100h
mov dx,string ; definimos la variable string
mov ah,9 ; 9 es copiado en el registro ah
int 21h ; colocamos una instrcción de interrupción
mov ah,4Ch
int 21h
string db 'Hola, Mundo!',0Dh,0Ah,'$' ; 0Dh es el caracter de retornar, 0Ah es el pie de
linea, el signo $ es para terminar la cadena
holalinux.asm
section .text
global _start
_start:
mov eax,4 ; ID de llamada al sistema: sys_write - escribir
mov ebx,1 ; descriptor de archivo para salida estandard
mov ecx,string ; dirección de string
mov edx,length ; string length
int 80h ; llamada al sistema
mov eax,1 ; ID de llamada al sistema: sys_exit - salida
mov ebx,0 ; codigo 0 de salida: no error
int 80h ; llamada al sistema
section .data
string: db 'Hola Mundo!',0Ah ; string de salida
Página 10 de 66
Materia: Lenguaje Ensamblador Clave: F1265
length: equ 13 ; longitud del string
2. Plantilla básica
Antes de empezar quiero hacer paréntesis. (Supongo que alrededor del 80% trabajará desde
Windows así que desde ahora voy a continuar desde el entorno Windows).
Esto con la finalidad de reducir el tamaño del documento con las demostraciones para ambos
sistemas operativos.
Ok… Este programa consiste en el esqueleto que tiene básicamente un programa en ensamblador
haciendo uso de declaraciones, comentarios, funciones y constantes. Editamos nuestro archivo
esqueleto.asm y guardamos.
Este código realmente no es funcional y nuestro resultado es que manda como salida mensajes de
error al momento de la compilación debido a que algunas instrucciones están incompletas, pues
solo han sido colocadas en su respectivo lugar pero no se están manejando con su sintaxis correcta.
En este caso es enter en la línea 12, push en la línea 13 y pop en la línea 17.
Página 11 de 66
Materia: Lenguaje Ensamblador Clave: F1265
CÓDIGO:
esqueleto.asm
segment .data
;
; data inicializado
;
segment .bss
;
; data unitilizado
;
segment .text
global _func
_func:
enter n,0 ; línea 12
push ; guardar registros línea 13
;
; cuerpo de la funcion
;
pop ; devolver registros línea 17
mov eax,0 ; retornar valor
leave
ret
Otra forma de tener nuestra plantilla sería como sigue:
esqueleto2.asm
segment .data
;
; data inicializado
;
segment .bss
;
; data unitilizado
;
segment .text
Página 12 de 66
Materia: Lenguaje Ensamblador Clave: F1265
global _func
_func:
push ebp ; si necesitamos que esta instrucción se ejecute antes
mov ebp,esp ; copiamos ebp en esp
sub esp,n ; sustituimos por enter
push ; guardar registros
;
; cuerpo de la funcion
;
pop ; devolver registros
mov eax,0 ; retornar valor
mov esp,ebp
pop ebp
ret ; devolvemos el valor de la rutina
3. Ensamblando y enlazando con C: ejemplo mcd
En este programa veremos cómo podemos trabajar desde ensamblador con código fuente del
lenguaje C. Para esto, el ejemplo consiste en encontrar el máximo común divisor con el modo
sencillo, aquí editamos el archivo mcd.asm con nuestro respectivo código. Lo guardamos.
Luego creamos nuestro código en C, en este caso lo nombré codigoprincipal.c en el cual solo se
reciben y envían valores pues el algoritmo se ejecuta en código ensamblador. Lo guardamos.
Página 13 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Lo que sigue es hacer el constructor del ensamblado y enlazado, aquí el truco es por medio de un
archivo ejecutable por lotes el cual llamé construir.bat en el cual indicamos que sean limpiados los
archivos de salida que hayamos generado previamente con erase, luego establecemos variables de
recursos para el compilador Visual C/C++ (pues tengo instalado Visual Studio). Debo hacer énfasis
en que la línea marca @set BIN=C:Program FilesMicrosoft Visual Studio 12.0VCbin para que nos
funcione mejor la agreguemos al PATH en las variables de entorno, pues en esta ruta se encuentra
el ejecutable cl.exe (compilador de optimización x86). Luego análogamente a la opción -o de nasm
utilizamos -f para indicar que mande de salida ejecutable x86, luego utilizamos la opción --prefix
más _ para el argumento dado para todas las variables globales o externos, como en C. Lo cual va
de la mano con el compilador de optimización x86 que se encargará de codigoprincipal.c y mcd.obj,
y guardamos.
Acto seguido ejecutamos construir.bat desde consola damos Enter y esperamos a que el proceso
termine, luego revisamos los archivos de salida creados.
Página 14 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Por ultimo verificamos que nuestro ejecutable .exe si funcione.
CÓDIGO:
mcd.asm
segment data
segment bss
Página 15 de 66
Materia: Lenguaje Ensamblador Clave: F1265
segment text
global mcd
mcd:
push ebp
mov ebp,esp
mov eax,[ebp+8] ; x
mov ebx,[ebp+12] ; y
looptop:
cmp eax,0 ; if (x == 0) hemos terminado
je goback
cmp eax,ebx ; hacer que cierto valor x sea un numero mas grande
jge modulo
xchg eax,ebx ; intercambiar x & y
modulo:
cdq ; setup para division
idiv ebx ; dividir edxeax por ebx
mov eax,edx ; el residuo esta en edx
jmp looptop
goback:
mov eax,ebx ; retornar y
mov esp,ebp
pop ebp
ret
codigoprincipal.c
#include <stdio.h>
int mcd(int a,int b);
int main() {
int result;
int a;
int b;
Página 16 de 66
Materia: Lenguaje Ensamblador Clave: F1265
a = 46;
b = 90;
printf("%d y %d tienen un mcd de %dn",a,b,mcd(a,b));
a = 9863;
b = 41272;
printf("%d y %d tiene un mcd de %dn",a,b,mcd(a,b));
}
construir.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
@set BIN=C:Program FilesMicrosoft Visual Studio 12.0VCbin
nasm -f win32 mcd.asm --prefix _
cl codigoprincipal.c mcd.obj
4. Generando números aleatorios
Este programa consiste en usar el algoritmo inorder para generar un número entero aleatorio entre
un rango especificado ya sea entre números positivos y negativos.
Suponemos que con los ejemplos anteriores ya tenemos claro cuál es nuestro patrón de producción
a código final, por lo que no entraremos en tanto detalle redundando en cosas que debemos hacer.
Ok… editamos nuestro código en C que llamaremos codigo_random.c, en ensamblador
enteros_random.asm y nuestro script de builder construir_random.bat y vemos nuestro resultado.
Página 17 de 66
Materia: Lenguaje Ensamblador Clave: F1265
CÓDIGO:
enteros_random.asm
segment .data
segment .bss
segment .text
global enterorandom ; definimos nuestra variable global
enterorandom:
push ebp
mov ebp,esp
mov eax,[ebp+8] ; primer argumento
cmp eax,[ebp+12] ; asegurarse de que el primer argumento es menor
jl inorder
xchg eax,[ebp+12] ; intercambiar primero y segundo
mov [ebp+8],eax
inorder: ; creamos la funcion inorder entre preorder y postorder
rdtsc ; leer contador de marca de tiempo
shr eax,2
mov ebx,[ebp+12] ; el valor más grande
add ebx,1 ; sumar uno
sub ebx,[ebp+8] ; subtracción del valor delta
cdq ; limpiar edx
idiv ebx ; dividir edxeax por ebx
add edx,[ebp+8]
goback:
mov eax,edx
mov esp,ebp
pop ebp
ret
Página 18 de 66
Materia: Lenguaje Ensamblador Clave: F1265
codigo_random.c
#include <stdio.h>
int enterorandom(int menor,int mayor);
int main() {
int i;
int a;
int b;
a = 1;
b = 18;
printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b));
a = 5500;
b = 100;
printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b));
a = -20;
b = 20;
printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b));
}
construir_random.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 enteros_random.asm --prefix _
cl codigo_random.c enteros_random.obj
Página 19 de 66
Materia: Lenguaje Ensamblador Clave: F1265
5. Encontrando números primos
Aquí trabajamos con el manejo de entrada y salida de datos definidos por el usuario por medio de
un programa que se encarga de encontrar los números primos entre una rango que debe ser
especificado al inicio de ejecución.
Para esto se codificaron los archivos codigo_primo.c, primo.asm, entrada.asm, salida.asm y
construir_primo.bat, nuestro resultado es como se muestra en la imagen.
CÓDIGO:
primo.asm
segment .data
inferior_prompt: db "Valor inferior a probar: ",0
superior_prompt: db "Valor superior a probar: ",0
newline: db 10,0
segment .bss
inferior: resd 1
superior: resd 1
recorrer: resd 1
factor: resd 1
segment .text
extern out_integer
extern in_integer
extern out_string
global encontrar_primos
encontrar_primos:
Página 20 de 66
Materia: Lenguaje Ensamblador Clave: F1265
enter 0,0
pushad
pushfd
; pedir límites superior e inferior
push dword inferior_prompt
call in_integer
pop ebx
mov [inferior],eax
or eax,0x00000001
mov [recorrer],eax
push dword superior_prompt
call in_integer
pop ebx
mov [superior],eax
mov dword [factor],2
; parte superior del bucle de prueba
factortest:
mov eax,[factor] ; prueba para el factor mas grande
imul eax,eax
cmp [recorrer],eax
jl encontrar
mov eax,[recorrer] ; prueba para el acarreo de división
mov ebx,[factor]
cdq
idiv ebx
cmp edx,0
je siguiente
add dword [factor],1 ; empujar factor y ciclar
jmp factortest
Página 21 de 66
Materia: Lenguaje Ensamblador Clave: F1265
; encontrar un primo
encontrar:
push dword [recorrer]
call out_integer
pop eax
push dword newline
call out_string
pop eax
; pasar al siguiente primo candidato
siguiente:
mov eax,[recorrer]
add eax,2
cmp eax,[superior]
jg terminado
mov [recorrer],eax
mov dword [factor],2
jmp factortest
terminado:
popfd
popad
mov eax,0
leave
ret
codigo_primo.c
void encontrar_primos(void);
int main()
{
encontrar_primos();
}
Página 22 de 66
Materia: Lenguaje Ensamblador Clave: F1265
entrada.asm
segment .data
segment .bss
char_hold: resd 1
str_hold: resb 20
str_len: equ $-str_hold-1
value: resd 1
segment .text
extern out_string
extern getchar
global in_char
in_char:
enter 0,0
pushad
pushfd
push dword [ebp+8]
call out_string
pop eax
mov byte [char_hold],' '
call getchar
cmp eax,10
jz .in_char_finish
mov [char_hold],al
Página 23 de 66
Materia: Lenguaje Ensamblador Clave: F1265
.in_char_flush:
call getchar
cmp eax,10
jnz .in_char_flush
.in_char_finish:
popfd
popad
mov al,[char_hold]
leave
ret
global in_string
in_string:
enter 0,0
pushad
pushfd
push dword [ebp+8]
call out_string
pop eax
mov ebx,str_hold ; dirección para almacenar cadena
mov byte [ebx],0
mov ecx,str_len ; longitud máxima de la cadena
.in_string_loop:
call getchar
Página 24 de 66
Materia: Lenguaje Ensamblador Clave: F1265
cmp eax,10
jz .in_string_finish
mov [ebx],al
add ebx,1
mov byte [ebx],0
sub ecx,1
jnz .in_string_loop
.in_string_flush:
call getchar
cmp eax,10
jnz .in_string_flush
.in_string_finish:
popfd
popad
mov eax,str_hold
leave
ret
global in_integer
in_integer:
enter 0,0
pushad
pushfd
Página 25 de 66
Materia: Lenguaje Ensamblador Clave: F1265
push dword [ebp+8]
call in_string
pop ebx
xor ecx,ecx
.in_integer_loop:
xor ebx,ebx
mov bl,[eax]
cmp bl,0x30
jl .in_integer_finish
cmp bl,0x39
jg .in_integer_finish
sub ebx,0x30
mov edx,ecx
shl edx,1
shl ecx,3
add ecx,edx
add ecx,ebx
add eax,1
jmp .in_integer_loop
.in_integer_finish:
mov [value],ecx
popfd
popad
mov eax,[value]
leave
Página 26 de 66
Materia: Lenguaje Ensamblador Clave: F1265
ret
salida.asm
%define CF_BIT 0x00000001
%define PF_BIT 0x00000004
%define AF_BIT 0x00000010
%define ZF_BIT 0x00000040
%define SF_BIT 0x00000080
%define DF_BIT 0x00000400
%define OF_BIT 0x00000800
; El segmento de datos ;;;;;;;;;;;;;;;;
segment .data
string_fmt: db "%s",0
integer_fmt: db "%d",0
flag_string: db "flags: ",0
cf_string: db "CF ",0
pf_string: db "PF ",0
af_string: db "AF ",0
zf_string: db "ZF ",0
sf_string: db "SF ",0
df_string: db "DF ",0
of_string: db "OF ",0
newline_string: db 10,0
hex_reg_fmt: db "eax: 0x%.8X ebx: 0x%.8X ecx: 0x%.8X edx: 0x%.8X",10
db 0
Página 27 de 66
Materia: Lenguaje Ensamblador Clave: F1265
dec_reg_fmt: db "eax: %d ebx: %d ecx: %d edx: %d",10
db 0
; El segmento bss ;;;;;;;;;;;;;;;;
segment .bss
flags: resd 1
; El segmento de texto ;;;;;;;;;;;;;;;;
segment .text
extern printf
global out_string
out_string:
enter 0,0
pushad
pushfd
push dword [ebp+8]
push dword string_fmt
call printf
pop ecx
pop ecx
popfd
popad
leave
ret
global out_flags
Página 28 de 66
Materia: Lenguaje Ensamblador Clave: F1265
out_flags:
enter 0,0
pushad
pushfd
push dword flag_string
call out_string
pop eax
mov eax,[esp] ; obtener una copia de las banderas
mov [flags],eax
; La bandera de acarreo (CF)
mov eax,[flags]
test eax,CF_BIT
jz cf_not
push cf_string
call out_string
pop eax
cf_not:
; La bandera de paridad (PF)
mov eax,[flags]
test eax,PF_BIT
jz pf_not
push pf_string
call out_string
pop eax
pf_not:
Página 29 de 66
Materia: Lenguaje Ensamblador Clave: F1265
; La bandera de acarreo auxiliar
mov eax,[flags]
test eax,AF_BIT
jz af_not
push af_string
call out_string
pop eax
af_not:
; La bandera de cero
mov eax,[flags]
test eax,ZF_BIT
jz zf_not
push zf_string
call out_string
pop eax
zf_not:
; La bandera de signo
mov eax,[flags]
test eax,SF_BIT
jz sf_not
push sf_string
call out_string
pop eax
sf_not:
; La bandera de dirección
mov eax,[flags]
test eax,DF_BIT
Página 30 de 66
Materia: Lenguaje Ensamblador Clave: F1265
jz df_not
push df_string
call out_string
pop eax
df_not:
; La bandera de desbordamiento
mov eax,[flags]
test eax,OF_BIT
jz of_not
push of_string
call out_string
pop eax
of_not:
; Un salto de línea
push dword newline_string
call out_string
pop eax
popfd
popad
leave
ret
; ----------------------------
global out_hex_registers
out_hex_registers:
enter 0,0
Página 31 de 66
Materia: Lenguaje Ensamblador Clave: F1265
pushad
pushfd
push edx
push ecx
push ebx
push eax
push dword hex_reg_fmt
call printf
add esp,20
popfd
popad
leave
ret
global out_integer
out_integer:
enter 0,0
pushad
pushfd
push dword [ebp+8]
push dword integer_fmt
call printf
pop ecx
pop ecx
Página 32 de 66
Materia: Lenguaje Ensamblador Clave: F1265
popfd
popad
leave
ret
global out_dec_registers
out_dec_registers:
enter 0,0
pushad
pushfd
push edx
push ecx
push ebx
push eax
push dword dec_reg_fmt
call printf
add esp,20
popfd
popad
leave
ret
construir_primo.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
Página 33 de 66
Materia: Lenguaje Ensamblador Clave: F1265
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 primo.asm --prefix _
nasm -f win32 entrada.asm --prefix _
nasm -f win32 salida.asm --prefix _
cl codigo_primo.c primo.obj entrada.obj salida.obj
Además, anexo el script constructor para Linux (por si las dudas). Para los Linuxeros.
construir_primo_linux
nasm -f elf primo.asm
nasm -f elf entrada.asm
nasm -f elf salida.asm
gcc codigo_primo.c primo.o entrada.o salida.o -o codigo_primo
6. Manipulación de bits: desplazando y alternando
Este programa es una colección de métodos para practicar con las variantes que podemos codificar
para mover bits con la bandera de acarreo (CF, con los 16 bits) tanto a la derecha como a la izquierda.
Para esto, se ha definido el archivo mover.asm que es la colección de métodos, los archivos:
aritmetica_izquierda.c, aritmetica_derecha.c, logica_izquierda.c, logica_derecha.c,
alternar_izquierda.c, alternar_derecha.c, acarreo_alternar_izquierda.c y
acarreo_alternar_derecha.c para llamar cada método por separado. Reutilizamos el archivo con el
código de salida.asm para no tener problemas con los caracteres de salida y mostrar.asm de donde
invocamos la función encargada de trabajar con las cadenas de bits a mostrar. Para compilarlo
reutilizamos el constructor del ejemplo anterior y lo adaptamos a los archivos de código creados
para la manipulación de bits, en nuestro caso podemos nombrarlo construir_mover_bits.bat, y una
vez creados nuestros ejecutables probamos uno por uno para ver el resultado por cada método.
Página 34 de 66
Materia: Lenguaje Ensamblador Clave: F1265
CÓDIGO:
mover.asm
segment .data
segment .bss
segment .text
extern mostrar_ax
global logica_izquierda
logica_izquierda:
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
shl ax,1
call mostrar_ax
shl ax,1
call mostrar_ax
popad
leave
ret
Página 35 de 66
Materia: Lenguaje Ensamblador Clave: F1265
global logica_derecha
logica_derecha:
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
shr ax,1
call mostrar_ax
shr ax,1
call mostrar_ax
popad
leave
ret
global aritmetica_izquierda
aritmetica_izquierda:
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
sal ax,1
call mostrar_ax
sal ax,1
call mostrar_ax
popad
leave
ret
global aritmetica_derecha
aritmetica_derecha:
Página 36 de 66
Materia: Lenguaje Ensamblador Clave: F1265
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
sar ax,1
call mostrar_ax
sar ax,1
call mostrar_ax
popad
leave
ret
global alternar_izquierda
alternar_izquierda:
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
rol ax,1
call mostrar_ax
rol ax,1
call mostrar_ax
popad
leave
ret
global alternar_derecha
alternar_derecha:
enter 0,0
pushad
Página 37 de 66
Materia: Lenguaje Ensamblador Clave: F1265
mov ax,0x8002
call mostrar_ax
ror ax,1
call mostrar_ax
ror ax,1
call mostrar_ax
popad
leave
ret
global acarreo_alternar_izquierda
acarreo_alternar_izquierda:
enter 0,0
pushad
mov ax,0x8002
call mostrar_ax
rcl ax,1
call mostrar_ax
rcl ax,1
call mostrar_ax
popad
leave
ret
global acarreo_alternar_derecha
acarreo_alternar_derecha:
enter 0,0
pushad
mov ax,0x8002
Página 38 de 66
Materia: Lenguaje Ensamblador Clave: F1265
call mostrar_ax
rcr ax,1
call mostrar_ax
rcr ax,1
call mostrar_ax
rcr ax,1
call mostrar_ax
popad
leave
ret
aritmetica_izquierda.c
#include <stdio.h>
void aritmetica_izquierda(void);
int main()
{
aritmetica_izquierda();
}
aritmetica_derecha.c
#include <stdio.h>
void aritmetica_derecha(void);
int main()
{
aritmetica_derecha();
}
logica_izquierda.c
#include <stdio.h>
Página 39 de 66
Materia: Lenguaje Ensamblador Clave: F1265
void logica_izquierda(void);
int main()
{
logica_izquierda();
}
logica_derecha.c
#include <stdio.h>
void logica_derecha(void);
int main()
{
logica_derecha();
}
alternar_izquierda.c
#include <stdio.h>
void alternar_izquierda(void);
int main()
{
alternar_izquierda();
}
alternar_derecha.c
#include <stdio.h>
void alternar_derecha(void);
int main()
{
Página 40 de 66
Materia: Lenguaje Ensamblador Clave: F1265
alternar_derecha();
}
acarreo_alternar_izquierda.c
#include <stdio.h>
void acarreo_alternar_izquierda(void);
int main()
{
acarreo_alternar_izquierda();
}
acarreo_alternar_derecha.c
#include <stdio.h>
void acarreo_alternar_derecha(void);
int main()
{
acarreo_alternar_derecha();
}
salida.asm
%define CF_BIT 0x00000001
%define PF_BIT 0x00000004
%define AF_BIT 0x00000010
%define ZF_BIT 0x00000040
%define SF_BIT 0x00000080
%define DF_BIT 0x00000400
%define OF_BIT 0x00000800
; El segmento de datos ;;;;;;;;;;;;;;;;
segment .data
Página 41 de 66
Materia: Lenguaje Ensamblador Clave: F1265
string_fmt: db "%s",0
integer_fmt: db "%d",0
flag_string: db "flags: ",0
cf_string: db "CF ",0
pf_string: db "PF ",0
af_string: db "AF ",0
zf_string: db "ZF ",0
sf_string: db "SF ",0
df_string: db "DF ",0
of_string: db "OF ",0
newline_string: db 10,0
hex_reg_fmt: db "eax: 0x%.8X ebx: 0x%.8X ecx: 0x%.8X edx: 0x%.8X",10
db 0
dec_reg_fmt: db "eax: %d ebx: %d ecx: %d edx: %d",10
db 0
; El segmento bss ;;;;;;;;;;;;;;;;
segment .bss
flags: resd 1
; El segmento de texto ;;;;;;;;;;;;;;;;
segment .text
extern printf
global out_string
out_string:
enter 0,0
pushad
pushfd
push dword [ebp+8]
push dword string_fmt
call printf
Página 42 de 66
Materia: Lenguaje Ensamblador Clave: F1265
pop ecx
pop ecx
popfd
popad
leave
ret
global out_flags
out_flags:
enter 0,0
pushad
pushfd
push dword flag_string
call out_string
pop eax
mov eax,[esp] ; obtener una copia de las banderas
mov [flags],eax
; La bandera de acarreo (CF)
mov eax,[flags]
test eax,CF_BIT
jz cf_not
push cf_string
call out_string
pop eax
cf_not:
; La bandera de paridad (PF)
mov eax,[flags]
test eax,PF_BIT
jz pf_not
push pf_string
call out_string
Página 43 de 66
Materia: Lenguaje Ensamblador Clave: F1265
pop eax
pf_not:
; La bandera de acarreo auxiliar
mov eax,[flags]
test eax,AF_BIT
jz af_not
push af_string
call out_string
pop eax
af_not:
; La bandera de cero
mov eax,[flags]
test eax,ZF_BIT
jz zf_not
push zf_string
call out_string
pop eax
zf_not:
; La bandera de signo
mov eax,[flags]
test eax,SF_BIT
jz sf_not
push sf_string
call out_string
pop eax
sf_not:
; La bandera de dirección
mov eax,[flags]
test eax,DF_BIT
jz df_not
push df_string
call out_string
pop eax
df_not:
Página 44 de 66
Materia: Lenguaje Ensamblador Clave: F1265
; La bandera de desbordamiento
mov eax,[flags]
test eax,OF_BIT
jz of_not
push of_string
call out_string
pop eax
of_not:
; Un salto de línea
push dword newline_string
call out_string
pop eax
popfd
popad
leave
ret
; ----------------------------
global out_hex_registers
out_hex_registers:
enter 0,0
pushad
pushfd
push edx
push ecx
push ebx
push eax
push dword hex_reg_fmt
call printf
add esp,20
popfd
Página 45 de 66
Materia: Lenguaje Ensamblador Clave: F1265
popad
leave
ret
global out_integer
out_integer:
enter 0,0
pushad
pushfd
push dword [ebp+8]
push dword integer_fmt
call printf
pop ecx
pop ecx
popfd
popad
leave
ret
global out_dec_registers
out_dec_registers:
enter 0,0
pushad
pushfd
push edx
push ecx
push ebx
push eax
push dword dec_reg_fmt
call printf
add esp,20
Página 46 de 66
Materia: Lenguaje Ensamblador Clave: F1265
popfd
popad
leave
ret
mostrar.asm
segment .data
string_ax: db " "
db " CF="
string_cf: db 0,10,0
segment .bss
segment .text
extern out_string
global mostrar_ax
mostrar_ax:
enter 0,0
pushad
pushfd
mov byte [string_cf],'1'
jc acarreo
mov byte [string_cf],'0'
acarreo:
mov ebx,0
looptop:
rol ax,1
jc uno
mov byte [string_ax+ebx],'0'
jmp siguiente
uno:
mov byte [string_ax+ebx],'1'
Página 47 de 66
Materia: Lenguaje Ensamblador Clave: F1265
siguiente:
inc ebx
cmp ebx,16
jne looptop
push string_ax
call out_string
pop ebx
popfd
popad
leave
ret
construir_mover_bits.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 mostrar.asm --prefix _
nasm -f win32 salida.asm --prefix _
nasm -f win32 mover.asm --prefix _
cl logica_izquierda.c mostrar.obj salida.obj mover.obj
cl logica_derecha.c mostrar.obj salida.obj mover.obj
cl aritmetica_izquierda.c mostrar.obj salida.obj mover.obj
cl aritmetica_derecha.c mostrar.obj salida.obj mover.obj
cl alternar_izquierda.c mostrar.obj salida.obj mover.obj
cl alternar_derecha.c mostrar.obj salida.obj mover.obj
cl acarreo_alternar_izquierda.c mostrar.obj salida.obj mover.obj
cl acarreo_alternar_derecha.c mostrar.obj salida.obj mover.obj
Para construirlo en Linux aplicaríamos la misma lógica, y la sintaxis del ejemplo anterior.
Página 48 de 66
Materia: Lenguaje Ensamblador Clave: F1265
7. Operaciones booleanas: and, or, xor, not
En este programa se implementan las operaciones booleanas and, or, xor y not, codificando
funciones específicas para cada tipo de operación, accediendo a las banderas de paridad, zero y
signo. Teniendo esta idea necesitamos código de prueba para mostrar los bits originales sobre los
cuales se harán las operaciones. Entonces hacemos lo siguiente.
Como en el ejemplo anterior, creamos en este caso nuestra colección de las funciones que realizan
cada tipo de operación booleana y anexamente nuestro código de prueba que genera los bits
originales que se utilizan como prueba con las banderas. Nuestros recursos son modos_boolean.asm
que es nuestra colección de funciones, los archivos de código C que son: and.c, or.c, xor.c, not.c y
test.c que implementan cada función, reutilizamos mostrar.asm, salida.asm y nuestro constructor
para nuestros recursos de código como en el ejemplo anterior. Ahora vemos nuestro resultado.
CÓDIGO:
modos_boolean.asm
segment .data
segment .bss
segment .text
Prueba original
con las banderas.
Implementando
las funciones.
Página 49 de 66
Materia: Lenguaje Ensamblador Clave: F1265
extern showal
extern out_flags
; funcion operacion and
global andbits
andbits:
enter 0,0
pushad
mov al,11110000b
call showal
mov al,00110011b
call showal
mov al,00110011b
and al,11110000b
call showal
popad
leave
ret
; funcion operacion or
global orbits
orbits:
enter 0,0
pushad
mov al,11110000b
call showal
mov al,00110011b
call showal
mov al,00110011b
or al,11110000b
call showal
popad
Página 50 de 66
Materia: Lenguaje Ensamblador Clave: F1265
leave
ret
; funcion operacion xor
global xorbits
xorbits:
enter 0,0
pushad
mov al,11110000b
call showal
mov al,00110011b
call showal
mov al,00110011b
xor al,11110000b
call showal
popad
leave
ret
; funcion operacion not
global notbits
notbits:
enter 0,0
pushad
mov al,00110011b
call showal
mov al,00110011b
not al
call showal
popad
leave
ret
Página 51 de 66
Materia: Lenguaje Ensamblador Clave: F1265
; funcion de prueba, bits originales
global testbits
testbits:
enter 0,0
pushad
mov al,11001100b
call showal
mov al,00110011b
call showal
mov al,00110011b
test al,11001100b
call out_flags
mov al,11100011b
call showal
mov al,11101100b
call showal
mov al,11100011b
test al,11101100b
call out_flags
popad
leave
ret
test.c
#include <stdio.h>
void testbits(void);
int main(){
testbits();
}
Página 52 de 66
Materia: Lenguaje Ensamblador Clave: F1265
and.c
#include <stdio.h>
void andbits(void);
int main() {
andbits();
}
or.c
#include <stdio.h>
void orbits(void);
int main(){
orbits();
}
xor.c
#include <stdio.h>
void xorbits(void);
int main(){
xorbits();
}
not.c
#include <stdio.h>
void notbits(void);
int main(){
notbits();
}
Página 53 de 66
Materia: Lenguaje Ensamblador Clave: F1265
salida.asm
“reutilizamos el del ejemplo anterior”
mostrar.asm
“reutilizamos el del ejemplo anterior”
construir_modos_boolean.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 mostrar.asm --prefix _
nasm -f win32 salida.asm --prefix _
nasm -f win32 modos_boolean.asm --prefix _
cl and.c modos_boolean.obj mostrar.obj salida.obj
cl or.c modos_boolean.obj mostrar.obj salida.obj
cl xor.c modos_boolean.obj mostrar.obj salida.obj
cl not.c modos_boolean.obj mostrar.obj salida.obj
cl test.c modos_boolean.obj mostrar.obj salida.obj
y para Linux.
construir_modos_boolean_linux
rm -f *.o
rm -f and
rm -f or
rm -f xor
rm -f not
Página 54 de 66
Materia: Lenguaje Ensamblador Clave: F1265
rm -f test
nasm -f elf salida.asm
nasm -f elf mostrar.asm
nasm -f elf modos_boolean.asm
gcc and.c salida.o modos_boolean.o mostrar.o -o and
gcc or.c salida.o modos_boolean.o mostrar.o -o or
gcc xor.c salida.o modos_boolean.o mostrar.o -o xor
gcc not.c salida.o modos_boolean.o mostrar.o -o not
gcc test.c salida.o modos_boolean.o mostrar.o -o test
8. Elección sin árbol: escoger número más grande
En este programa hacemos uso del algoritmo de búsqueda de una pasada para encontrar el número
más grandes entre dos valores ingresados al inicio de ejecución (sin importar orden y tamaño de
número). En este ejemplo podemos revisar cómo trabajar con simples estructuras de control para
producir resultados en base a valores de entrada.
Para esto codificamos escoger.asm que contiene el algoritmo y las variables, codigo_escoger.c para
utilizar nuestra función, enlazar y compilar nuestro ejecutable, reutilizamos entrada.asm y
salida.asm de ejemplos anteriores y adaptamos nuestro constructor (construir_escoger.bat) de
acuerdo a nuestros recursos de código. Nuestro resultado es el siguiente.
CÓDIGO:
escoger.asm
segment .data
Página 55 de 66
Materia: Lenguaje Ensamblador Clave: F1265
ask1: db "Ingrese primer numero: ",0
ask2: db "Ingrese segundo numero: ",0
tell db "El numero mas grande es: ",0
newline db 10,0
segment .bss
valor1: resd 1
segment .text
extern in_integer
extern out_integer
extern out_string
global escoger
escoger:
enter 0,0
push dword ask1
call in_integer
pop ebx
mov [valor1],eax
push dword ask2
call in_integer
pop ebx
xor ebx,ebx ; zero ebx
cmp eax,[valor1] ; comparar los dos valores
setg bl ; establecer bl=1 si valor2 > valor1, sino cero
not ebx ; cumplimiento del primero
Página 56 de 66
Materia: Lenguaje Ensamblador Clave: F1265
inc ebx ; cumplimiento del segundo
mov ecx,ebx ; copiar en ecx
and ecx,eax ; ecx es: o segundo valor, o cero
not ebx ; ebx es cero o todos
and ebx,[valor1] ; ebx es cero o primer de valor
or ecx,ebx ; ecx es ya sea primer o segundo valor
push dword tell
call out_string
pop ebx
push ecx
call out_integer
pop ebx
push dword newline
call out_string
pop ebx
leave
ret
codigo_escoger.c
#include <stdio.h>
void escoger(void);
int main() {
escoger();
}
entrada.asm
Página 57 de 66
Materia: Lenguaje Ensamblador Clave: F1265
“reutilizamos de un ejemplo anterior”
salida.asm
“reutilizamos el del ejemplo anterior”
construir_escoger.c
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 escoger.asm --prefix _
nasm -f win32 salida.asm --prefix _
nasm -f win32 entrada.asm --prefix _
cl codigo_escoger.c entrada.obj salida.obj escoger.obj
Y para Linux, pues ya saben...
9. Arreglos: definiendo y manejando direcciones
Este programa depende más de código C que de ensamblador. En este último solo definimos el
manejo de las direcciones en memoria y en lenguaje C codificamos el comportamiento de los
arreglos con valores preestablecidos y la orden de salida. Para que se perciba como podemos
trabajar con ellos se han creado 2 variantes la primera es un arreglo simple donde multiplicamos
sus valores y la segunda es un arreglo multidimensional donde los valores son ordenados por el
método bubble sort, aunque en la salida no se pueda apreciar en primera instancia.
Versión 1: Aquí los recursos de código son codigo_por_cuatro.c, por_cuatro.asm y
construir_arreglos.bat con lo cual obtendremos el siguiente resultado.
Página 58 de 66
Materia: Lenguaje Ensamblador Clave: F1265
Versión 2:
Aquí los recursos de código son codigo_ordenar.c, ordenar.asm y construir_arreglos.bat con lo cual
obtendremos el siguiente resultado. Aquí los valores de cada posición han sido ordenados por el
método bubble sort (ordenamiento burbuja).
CÓDIGO:
codigo_por_cuatro.c
#include <stdio.h>
void por_cuatro(int tamanio,int arr[]);
int main()
{
int i;
int tamanio=10;
int array[10];
for(i=0; i<tamanio; i++) {
array[i] = i;
printf("%d ",array[i]);
}
printf("n");
por_cuatro(tamanio,array);
for(i=0; i<tamanio; i++) {
printf("%d ",array[i]);
}
Página 59 de 66
Materia: Lenguaje Ensamblador Clave: F1265
printf("n");
}
por_cuatro.asm
segment .data
segment .bss
segment .text
global por_cuatro
por_cuatro:
push ebp
mov ebp,esp
mov ebx,[ebp+12] ; direccion del arreglo
mov ecx,[ebp+8] ; tamaño del arreglo
top:
mov eax,[ebx]
shl eax,2
mov [ebx],eax
add ebx,4
loop top
leave
ret
codigo_ordenar.c
#include <stdio.h>
void a_ordenar(int tamanio,int arr[]);
int array[] = { 5,32,87,4,92,11,34,3,84,60,17 };
int main()
{
Página 60 de 66
Materia: Lenguaje Ensamblador Clave: F1265
int i;
int tamanio = sizeof(array) / sizeof(int);
for(i=0; i<tamanio; i++) {
printf("%d ",array[i]);
}
printf("n");
a_ordenar(tamanio,array);
for(i=0; i<tamanio; i++) {
printf("%d ",array[i]);
}
printf("n");
}
ordenar.asm
segment .data
segment .bss
segment .text
global a_ordenar
a_ordenar:
push ebp
mov ebp,esp
reiniciar:
mov ebx,[ebp+12] ; direccion del arreglo
mov ecx,[ebp+8] ; tamaño del arreglo
sub ecx,1
top:
mov eax,[ebx]
cmp eax,[ebx+4]
Página 61 de 66
Materia: Lenguaje Ensamblador Clave: F1265
jle noswap
xchg eax,[ebx+4]
mov [ebx],eax
jmp reiniciar
noswap:
add ebx,4
loop top
leave
ret
construir_arreglos.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 por_cuatro.asm --prefix _
nasm -f win32 ordenar.asm --prefix _
cl codigo_por_cuatro.c por_cuatro.obj
cl codigo_ordenar.c ordenar.obj
10. Punto flotante: ejemplo ecuación cuadrática
En este programa tratamos con números de punto flotante para que de acuerdo a este tipo de valor
llevemos a cabo instrucciones condicionales. El ejemplo elegido es el cálculo de la ecuación
cuadrática donde una solución puede ser positiva y otra negativa, enteras o de punto flotante,
infinito negativo e infinito positivo, etc. Digamos que, tratamos con una cuestión práctica donde se
requiere exactitud en los cálculos.
Para este caso los recursos de código creados son codigo_cuadratica.c, cuadratica.asm y
construir_cuadratica.bat, y el comportamiento que obtenemos es el siguiente.
Página 62 de 66
Materia: Lenguaje Ensamblador Clave: F1265
CÓDIGO:
cuadratica.asm
%define a qword [ebp+8]
%define b qword [ebp+16]
%define c qword [ebp+24]
%define solucion1 dword [ebp+32]
%define solucion2 dword [ebp+36]
%define rad qword [ebp-8]
%define recip_2a qword [ebp-16]
segment .data
menoscuatro: dw -4
segment .bss
segment .text
global cuadratica
cuadratica:
push ebp
mov ebp,esp
sub esp,16 ; dos espacios de trabajo double
Página 63 de 66
Materia: Lenguaje Ensamblador Clave: F1265
push ebx
fild word [menoscuatro] ; st: -4
fld a ; st: a, -4
fld c ; st: c, a, -4
fmulp st1 ; st: a*c, -4
fmulp st1 ; st: -4*a*c
fld b ; st: b, -4*a*c
fld b ; st: b, b, -4*a*c
fmulp st1 ; st: b*b, -4*a*c
faddp st1 ; st: b*b - 4*a*c
ftst ; comparar st0 a 0
fstsw ax ; ax = palabra de estado
sahf ; banderas = ah
jb no_solucion_real
fsqrt ; st: sqrt(b*b - 4*a*c)
fstp rad ; st: vacio, y radical almacenado
fld1 ; st: 1
fld a ; st: a, 1
fscale ; st: 2*a, 1
fdivp st1 ; st: 1/(2*a)
fst recip_2a ; st: 1/(2*a)
fld b ; st: b, 1/(2*a)
fld rad ; st: rad , b, 1/(2*a)
fsubrp st1 ; st: rad - b, 1/(2*a)
fmulp st1 ; st: (-b + rad )/(2*a)
mov ebx,solucion1
fstp qword [ebx] ; resultado en solucion1
fld b ; st: b
fld rad ; st: rad , b
fchs ; st: -rad , b
fsubrp st1 ; st: -rad - b
fmul recip_2a ; st: (-rad - b)/(2*a)
Página 64 de 66
Materia: Lenguaje Ensamblador Clave: F1265
mov ebx,solucion2
fstp qword [ebx] ; resultado en solucion2
mov eax,1 ; retornar valor
jmp quit
no_solucion_real:
mov eax,0
quit:
pop ebx
mov esp,ebp
pop ebp
ret
codigo_cuadratica.c
#include <stdio.h>
int cuadratica(double,double,double,double *,double *);
int main()
{
double a;
double b;
double c;
double solucion1;
double solucion2;
int cond;
do {
printf("na: ");
scanf("%lf",&a);
printf("b: ");
scanf("%lf",&b);
printf("c: ");
Página 65 de 66
Materia: Lenguaje Ensamblador Clave: F1265
scanf("%lf",&c);
cond = cuadratica(a,b,c,&solucion1,&solucion2);
if(cond == 0) {
printf("Sin solucion real.n");
} else {
printf("%g and %gn",solucion1,solucion2);
}
} while(1);
}
construir_cuadratica.bat
erase *.obj
erase *.exe
@set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
@set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft
SDKsWindowsv7.1ALib
nasm -f win32 cuadratica.asm --prefix _
cl codigo_cuadratica.c cuadratica.obj
FUENTES ANEXAS:
Las siguientes fuentes de información hacen referencia a documentos (e-books) publicados que son
de utilidad para estudiar la programación en lenguaje ensamblador, unas son mejores que otras
pero todas se complementan.
1. Richard Blum. Professional Assembly Language. Wiley Publishing, Inc.
2. Peter Abel. Lenguaje ensamblador y programación para IBM PC y compatibles. Pearson
Education, Inc.
3. Randall Hyde. The Art Of Assembly Language. No Starch Press, Inc.
4. Jeff Duntemann. Assembly Language Step-by-Step: Programming with Linux. Wiley
Publishing, Inc.
Página 66 de 66
Materia: Lenguaje Ensamblador Clave: F1265
5. Kip R. Irvine. Lenguaje ensamblador para computadoras basadas en Intel. Pearson
Education, Inc.
6. Joseph Cavanagh. X86 Assembly Language and C Fundamentals. CRC Press by Taylor &
Francis Group

Más contenido relacionado

La actualidad más candente

Principales características de QEMU
Principales características de QEMUPrincipales características de QEMU
Principales características de QEMUdegarden
 
Administración de procesos y del procesador
Administración de procesos y del procesadorAdministración de procesos y del procesador
Administración de procesos y del procesadorFernando Camacho
 
Sistemas operativos procesos
Sistemas operativos   procesosSistemas operativos   procesos
Sistemas operativos procesosayreonmx
 
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORAS
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORASORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORAS
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORASkevin vargas paredes
 
Storage networks
Storage networksStorage networks
Storage networksAhmed Nour
 
Tópicos Avanzados de Programación - Unidad 2 componentes y librerias
Tópicos Avanzados de Programación - Unidad 2 componentes y libreriasTópicos Avanzados de Programación - Unidad 2 componentes y librerias
Tópicos Avanzados de Programación - Unidad 2 componentes y libreriasJosé Antonio Sandoval Acosta
 
Modelo de 5 estados para sistemas operativos
Modelo de 5 estados para sistemas operativosModelo de 5 estados para sistemas operativos
Modelo de 5 estados para sistemas operativosLuis Dario Gomez
 
Modelo OSI capa de Red
Modelo OSI capa de RedModelo OSI capa de Red
Modelo OSI capa de RedCarlos Estrada
 
Estructura física y lógica del disco duro
Estructura física y lógica del disco duroEstructura física y lógica del disco duro
Estructura física y lógica del disco durogematic
 
Control de flujo por hardware o software,
Control de flujo  por hardware o software,Control de flujo  por hardware o software,
Control de flujo por hardware o software,Victor Mijangos
 
Cuestionario de Redes Informáticas
Cuestionario de Redes InformáticasCuestionario de Redes Informáticas
Cuestionario de Redes InformáticasLaddy Mathita
 
Procesos Interrupciones y Nucleo
 Procesos Interrupciones y Nucleo Procesos Interrupciones y Nucleo
Procesos Interrupciones y NucleoG Hoyos A
 
Gestion de memoria
Gestion de memoriaGestion de memoria
Gestion de memoriapuracastillo
 
Interfaces De Entrada Y Salida
Interfaces De Entrada Y SalidaInterfaces De Entrada Y Salida
Interfaces De Entrada Y SalidaBigbossH
 

La actualidad más candente (20)

Principales características de QEMU
Principales características de QEMUPrincipales características de QEMU
Principales características de QEMU
 
Tecnicas de Administracion de Memoria
Tecnicas de Administracion de MemoriaTecnicas de Administracion de Memoria
Tecnicas de Administracion de Memoria
 
Administración de procesos y del procesador
Administración de procesos y del procesadorAdministración de procesos y del procesador
Administración de procesos y del procesador
 
Sistemas operativos procesos
Sistemas operativos   procesosSistemas operativos   procesos
Sistemas operativos procesos
 
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORAS
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORASORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORAS
ORIGEN Y EVOLUCIÓN DE LAS REDES DE COMPUTADORAS
 
Storage networks
Storage networksStorage networks
Storage networks
 
Planificacion cpu
Planificacion cpuPlanificacion cpu
Planificacion cpu
 
Implementación de hilos
Implementación de hilos Implementación de hilos
Implementación de hilos
 
Tópicos Avanzados de Programación - Unidad 2 componentes y librerias
Tópicos Avanzados de Programación - Unidad 2 componentes y libreriasTópicos Avanzados de Programación - Unidad 2 componentes y librerias
Tópicos Avanzados de Programación - Unidad 2 componentes y librerias
 
Segmentacion de memoria
Segmentacion de memoriaSegmentacion de memoria
Segmentacion de memoria
 
Modelo de 5 estados para sistemas operativos
Modelo de 5 estados para sistemas operativosModelo de 5 estados para sistemas operativos
Modelo de 5 estados para sistemas operativos
 
Modelo OSI capa de Red
Modelo OSI capa de RedModelo OSI capa de Red
Modelo OSI capa de Red
 
Estructura física y lógica del disco duro
Estructura física y lógica del disco duroEstructura física y lógica del disco duro
Estructura física y lógica del disco duro
 
Control de flujo por hardware o software,
Control de flujo  por hardware o software,Control de flujo  por hardware o software,
Control de flujo por hardware o software,
 
Cuestionario de Redes Informáticas
Cuestionario de Redes InformáticasCuestionario de Redes Informáticas
Cuestionario de Redes Informáticas
 
Permisos ntfs
Permisos ntfsPermisos ntfs
Permisos ntfs
 
Procesos Interrupciones y Nucleo
 Procesos Interrupciones y Nucleo Procesos Interrupciones y Nucleo
Procesos Interrupciones y Nucleo
 
Gestion de memoria
Gestion de memoriaGestion de memoria
Gestion de memoria
 
Interfaces De Entrada Y Salida
Interfaces De Entrada Y SalidaInterfaces De Entrada Y Salida
Interfaces De Entrada Y Salida
 
UNIDAD 2 PROGRAMACIÓN BASICA
UNIDAD 2 PROGRAMACIÓN BASICAUNIDAD 2 PROGRAMACIÓN BASICA
UNIDAD 2 PROGRAMACIÓN BASICA
 

Destacado

Sistemas Inteligentes de Transporte - Planificación
Sistemas Inteligentes de Transporte - PlanificaciónSistemas Inteligentes de Transporte - Planificación
Sistemas Inteligentes de Transporte - PlanificaciónJulián Lara
 
Práctica final tercer parcial
Práctica final  tercer parcialPráctica final  tercer parcial
Práctica final tercer parcialAnibal Ulibarri
 
Lenguaje ensamblador nasm
Lenguaje ensamblador nasmLenguaje ensamblador nasm
Lenguaje ensamblador nasmgabo
 
Jerarquia de la memoria
Jerarquia de la memoriaJerarquia de la memoria
Jerarquia de la memoriazombra18
 
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...Software Guru
 
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...Introduccion a las herramientas libres GNU/Linux para la programacion de micr...
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...georgeguitar
 
El hardware de comunicaciones de datos
El hardware de comunicaciones de datosEl hardware de comunicaciones de datos
El hardware de comunicaciones de datosRoderick Cantera PTY
 
Computación sentimental
Computación sentimentalComputación sentimental
Computación sentimentalSoftware Guru
 
Lenguaje ensamblador basico
Lenguaje ensamblador basicoLenguaje ensamblador basico
Lenguaje ensamblador basicoGustavo Davila
 
52 ejercicios resueltos en pseudocodigo
52 ejercicios resueltos en pseudocodigo52 ejercicios resueltos en pseudocodigo
52 ejercicios resueltos en pseudocodigoBrivé Soluciones
 
DISPOSITIVOS DE CAPA 2 DEL MODELO OSI
DISPOSITIVOS DE CAPA 2 DEL MODELO OSIDISPOSITIVOS DE CAPA 2 DEL MODELO OSI
DISPOSITIVOS DE CAPA 2 DEL MODELO OSIEwing Ma
 
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)Miguel Angel Corona Lòpez
 

Destacado (15)

NASM
NASM NASM
NASM
 
Sistemas Inteligentes de Transporte - Planificación
Sistemas Inteligentes de Transporte - PlanificaciónSistemas Inteligentes de Transporte - Planificación
Sistemas Inteligentes de Transporte - Planificación
 
Práctica final tercer parcial
Práctica final  tercer parcialPráctica final  tercer parcial
Práctica final tercer parcial
 
Lenguaje ensamblador nasm
Lenguaje ensamblador nasmLenguaje ensamblador nasm
Lenguaje ensamblador nasm
 
Jerarquia de la memoria
Jerarquia de la memoriaJerarquia de la memoria
Jerarquia de la memoria
 
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...
Diseñando la Experiencia del Usuario con Sistemas Interactivos: ¿Cómo diseñam...
 
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...Introduccion a las herramientas libres GNU/Linux para la programacion de micr...
Introduccion a las herramientas libres GNU/Linux para la programacion de micr...
 
El hardware de comunicaciones de datos
El hardware de comunicaciones de datosEl hardware de comunicaciones de datos
El hardware de comunicaciones de datos
 
Lenguaje ensamblador
Lenguaje ensambladorLenguaje ensamblador
Lenguaje ensamblador
 
Computación sentimental
Computación sentimentalComputación sentimental
Computación sentimental
 
Lenguaje ensamblador basico
Lenguaje ensamblador basicoLenguaje ensamblador basico
Lenguaje ensamblador basico
 
Manejo de archivo
Manejo de archivoManejo de archivo
Manejo de archivo
 
52 ejercicios resueltos en pseudocodigo
52 ejercicios resueltos en pseudocodigo52 ejercicios resueltos en pseudocodigo
52 ejercicios resueltos en pseudocodigo
 
DISPOSITIVOS DE CAPA 2 DEL MODELO OSI
DISPOSITIVOS DE CAPA 2 DEL MODELO OSIDISPOSITIVOS DE CAPA 2 DEL MODELO OSI
DISPOSITIVOS DE CAPA 2 DEL MODELO OSI
 
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)
Microcontroladores pic (josé mª angulo usategui, ignacio angulo martínez)
 

Similar a programacion en lenguaje ensamblador con NASM

Similar a programacion en lenguaje ensamblador con NASM (20)

97132962-instalacion-de-open meetings-en-squeeze
 97132962-instalacion-de-open meetings-en-squeeze 97132962-instalacion-de-open meetings-en-squeeze
97132962-instalacion-de-open meetings-en-squeeze
 
Tuto y claves de fedora
Tuto y claves de fedoraTuto y claves de fedora
Tuto y claves de fedora
 
Mantención y administración de sistemas -samba
Mantención y administración de sistemas -sambaMantención y administración de sistemas -samba
Mantención y administración de sistemas -samba
 
Sesion3 del Curso de Lliurex
Sesion3 del Curso de LliurexSesion3 del Curso de Lliurex
Sesion3 del Curso de Lliurex
 
Openmeetings+En+Xp
Openmeetings+En+XpOpenmeetings+En+Xp
Openmeetings+En+Xp
 
Instalar Linux Y Windows En Un Mismo Disco
Instalar Linux Y Windows En Un Mismo DiscoInstalar Linux Y Windows En Un Mismo Disco
Instalar Linux Y Windows En Un Mismo Disco
 
Manual de programacion_en_batch_by_dhyablo
Manual de programacion_en_batch_by_dhyabloManual de programacion_en_batch_by_dhyablo
Manual de programacion_en_batch_by_dhyablo
 
Guia instalacion y configuracion nagios
Guia instalacion y configuracion nagiosGuia instalacion y configuracion nagios
Guia instalacion y configuracion nagios
 
Linux - Programas de utilería linux
Linux - Programas de utilería linuxLinux - Programas de utilería linux
Linux - Programas de utilería linux
 
Ubuntu
UbuntuUbuntu
Ubuntu
 
Linux
LinuxLinux
Linux
 
Requerimiento de windows y linux
Requerimiento de windows y linuxRequerimiento de windows y linux
Requerimiento de windows y linux
 
Nombre del maestro
Nombre del maestroNombre del maestro
Nombre del maestro
 
Enchanting en Linux Ubuntu
Enchanting en Linux UbuntuEnchanting en Linux Ubuntu
Enchanting en Linux Ubuntu
 
Freepascal
FreepascalFreepascal
Freepascal
 
Migración de Windows a Linux
Migración de Windows a LinuxMigración de Windows a Linux
Migración de Windows a Linux
 
Instalacion linux
Instalacion linuxInstalacion linux
Instalacion linux
 
Lab9
Lab9Lab9
Lab9
 
Curso iniciación en Constructor
Curso iniciación en ConstructorCurso iniciación en Constructor
Curso iniciación en Constructor
 
Curso iniciación en Constructor
Curso iniciación en ConstructorCurso iniciación en Constructor
Curso iniciación en Constructor
 

Más de フ乇丂ひ丂

Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)
Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)
Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)フ乇丂ひ丂
 
Gestor de archivos históricos
Gestor de archivos históricos Gestor de archivos históricos
Gestor de archivos históricos フ乇丂ひ丂
 
Fabrica tu propio cable VGA
Fabrica tu propio cable VGAFabrica tu propio cable VGA
Fabrica tu propio cable VGAフ乇丂ひ丂
 
Privilegios y funciones en MySQL
Privilegios y funciones en MySQLPrivilegios y funciones en MySQL
Privilegios y funciones en MySQLフ乇丂ひ丂
 
Compartir una impresora en red
Compartir una impresora en redCompartir una impresora en red
Compartir una impresora en redフ乇丂ひ丂
 
Asistencia remota y escritorio remoto en Windows
Asistencia remota y escritorio remoto en WindowsAsistencia remota y escritorio remoto en Windows
Asistencia remota y escritorio remoto en Windowsフ乇丂ひ丂
 
Establecer control de PCs en ciber
Establecer control de PCs en ciberEstablecer control de PCs en ciber
Establecer control de PCs en ciberフ乇丂ひ丂
 
Tester casero para cables de red
Tester casero para cables de redTester casero para cables de red
Tester casero para cables de redフ乇丂ひ丂
 
Programacion multiagente con JADE
Programacion multiagente con JADEProgramacion multiagente con JADE
Programacion multiagente con JADEフ乇丂ひ丂
 
Appcelerator Titanium Kinetic practices part 1
Appcelerator Titanium Kinetic practices part 1Appcelerator Titanium Kinetic practices part 1
Appcelerator Titanium Kinetic practices part 1フ乇丂ひ丂
 

Más de フ乇丂ひ丂 (12)

Tutorial Gitblit
Tutorial GitblitTutorial Gitblit
Tutorial Gitblit
 
Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)
Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)
Trabajo Recepcional de Objeto de Aprendizaje (My Chemical App)
 
Gestor de archivos históricos
Gestor de archivos históricos Gestor de archivos históricos
Gestor de archivos históricos
 
Fabrica tu propio cable VGA
Fabrica tu propio cable VGAFabrica tu propio cable VGA
Fabrica tu propio cable VGA
 
Access contra MySQL
Access contra MySQLAccess contra MySQL
Access contra MySQL
 
Privilegios y funciones en MySQL
Privilegios y funciones en MySQLPrivilegios y funciones en MySQL
Privilegios y funciones en MySQL
 
Compartir una impresora en red
Compartir una impresora en redCompartir una impresora en red
Compartir una impresora en red
 
Asistencia remota y escritorio remoto en Windows
Asistencia remota y escritorio remoto en WindowsAsistencia remota y escritorio remoto en Windows
Asistencia remota y escritorio remoto en Windows
 
Establecer control de PCs en ciber
Establecer control de PCs en ciberEstablecer control de PCs en ciber
Establecer control de PCs en ciber
 
Tester casero para cables de red
Tester casero para cables de redTester casero para cables de red
Tester casero para cables de red
 
Programacion multiagente con JADE
Programacion multiagente con JADEProgramacion multiagente con JADE
Programacion multiagente con JADE
 
Appcelerator Titanium Kinetic practices part 1
Appcelerator Titanium Kinetic practices part 1Appcelerator Titanium Kinetic practices part 1
Appcelerator Titanium Kinetic practices part 1
 

Último

SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVO
SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVOSISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVO
SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVOELIAMARYTOVARFLOREZD
 
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptx
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptxMacOS SISTEMA OPERATIVO CARACTERISTICAS.pptx
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptxcalzadillasluis134
 
Semana 5-Conceptualización del lenguaje de programación C++
Semana 5-Conceptualización del lenguaje de programación C++Semana 5-Conceptualización del lenguaje de programación C++
Semana 5-Conceptualización del lenguaje de programación C++luzgaray6
 
Theme design in Plone 6 - World Plone Day 2024
Theme design in Plone 6 - World Plone Day 2024Theme design in Plone 6 - World Plone Day 2024
Theme design in Plone 6 - World Plone Day 2024Leonardo J. Caballero G.
 
Introducción a Plone CMS - World Plone Day 2024
Introducción a Plone CMS - World Plone Day 2024Introducción a Plone CMS - World Plone Day 2024
Introducción a Plone CMS - World Plone Day 2024Leonardo J. Caballero G.
 
Presentación de html, css y javascript.
Presentación  de html, css y javascript.Presentación  de html, css y javascript.
Presentación de html, css y javascript.CeteliInmaculada
 

Último (6)

SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVO
SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVOSISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVO
SISTEMA INTEGRADO DE ADMINISTRACION FINANCIERA - SIAF MODULO ADMINISTRATIVO
 
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptx
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptxMacOS SISTEMA OPERATIVO CARACTERISTICAS.pptx
MacOS SISTEMA OPERATIVO CARACTERISTICAS.pptx
 
Semana 5-Conceptualización del lenguaje de programación C++
Semana 5-Conceptualización del lenguaje de programación C++Semana 5-Conceptualización del lenguaje de programación C++
Semana 5-Conceptualización del lenguaje de programación C++
 
Theme design in Plone 6 - World Plone Day 2024
Theme design in Plone 6 - World Plone Day 2024Theme design in Plone 6 - World Plone Day 2024
Theme design in Plone 6 - World Plone Day 2024
 
Introducción a Plone CMS - World Plone Day 2024
Introducción a Plone CMS - World Plone Day 2024Introducción a Plone CMS - World Plone Day 2024
Introducción a Plone CMS - World Plone Day 2024
 
Presentación de html, css y javascript.
Presentación  de html, css y javascript.Presentación  de html, css y javascript.
Presentación de html, css y javascript.
 

programacion en lenguaje ensamblador con NASM

  • 1. Lenguaje Ensamblador: Guia práctica...............................................................................................2 ¿QUÉ NECESITO? ...............................................................................................................................2 ¿QUÉ HAGO CON TODOS LOS RECURSOS QUE NECESITO? ..............................................................3 ¡A PROGRAMAR! ...............................................................................................................................7 1. Hola mundo ...............................................................................................................................7 2. Plantilla básica.........................................................................................................................10 3. Ensamblando y enlazando con C: ejemplo mcd......................................................................12 4. Generando números aleatorios...............................................................................................16 5. Encontrando números primos.................................................................................................19 6. Manipulación de bits: desplazando y alternando...................................................................33 7. Operaciones booleanas: and, or, xor, not...............................................................................48 8. Elección sin árbol: escoger número más grande.....................................................................54 9. Arreglos: definiendo y manejando direcciones.......................................................................57 10. Punto flotante: ejemplo ecuación cuadrática.......................................................................61 FUENTES ANEXAS: ...........................................................................................................................65
  • 2. Página 2 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Lenguaje Ensamblador: Guia práctica Jesús Antonio Ferrer Sánchez Para programar en lenguaje ensamblador escogí la especificación NASM (Netwide Assembler) que soporta las plataformas Windows y Unix (Linux), dejando aparte las que son conocidas por defecto para cada sistema operativo (MASM para Windows, TSAM para Mac y GAS para Linux). Seguro piensan ¿Cuál es la razón? La respuesta es que el propio nombre lo dice “Netwide Assembler”, es decir, existe una comunidad que mantiene actualizada documentación y herramientas para programar en lenguaje ensamblador. Bueno… manos a la obra, para empezar necesitamos visitar el sitio Web donde se encuentra los más importante que necesitaremos http://www.nasm.us/, hecho esto la siguiente cuestión es ¿Qué vamos a utilizar de allí? Pues lo siguiente: ¿QUÉ NECESITO? 1. La documentación, que está aquí: http://www.nasm.us/docs.php aunque realmente existe documentación más actualizada como en su sitio de Sourceforge o Git, por ejemplo. Lo más recomendable es utilizar la versión estable. 2. El compilador e intérprete, que está aquí: http://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D estando allí debemos abrir la primera carpeta de arriba hacia abajo que no contenga la terminación rc, por ejemplo abriremos la carpeta 2.11.05 (fijate que no dice 2.11.05rc) estando dentro bajaremos el compilador e intérprete de acuerdo a nuestro tipo sistema operativo especifico, que se identifican con los nombre de las carpeta linux/, macosx/ y win32/ para los usuario Windows x64 no se espanten porque dice win32 pueden lograr mayor compatibilidad con DOSBox (http://www.dosbox.com/). Ahora hago una distinción para Windows y Linux (para Mac no, porque soy super pobre). 2.1. Para los usuarios Windows recomiendo que descarguen el instalador (nasm-2.11.05- installer.exe, por ejemplo) esto para su mayor comodidad. 2.2. Para los usuarios Linux no es necesario entrar a la carpeta linux/ puesto que lo recomendable es trabajar con el archivo que se identifica con la terminación .tar.gz (nasm- 2.11.05.tar.gz, por ejemplo) ya verán porque más adelantito. 3. El enlazador para Windows OS (para Linux no es necesario): UNIVERSIDAD JUÁREZ AUTÓNOMA DE TABASCO DIVISIÓN ACADÉMICA DE INFORMÁTICA Y SISTEMAS
  • 3. Página 3 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Necesitamos solamente Alink el cual trabaja en conjunto con Nasm para la plataforma Windows, este es un complemento totalmente necesario. Para descargarlo debemos ir a: http://alink.sourceforge.net/download.html estando aquí seleccionar Download ALINK (Win32 version) el cual deberá mandarnos un archivo nombrado al_al.zip 4. Un editor en consola: Ya sea Vi, Vim o nano, para mi comodidad elegí nano porque viene por defecto en Linux y funciona igualito en Windows, ya saben para conseguirlo ir a: http://www.nano-editor.org/ para conseguirlo para Windows navegar hasta: http://www.nano- editor.org/dist/v2.2/NT/nano-2.2.6.zip y listo habremos descargado nano para Windows. Esto lo hago para no perder la costumbre de usar la línea de comandos. Ahora la siguiente cuestión es ¿Qué hago con todo esto… para empezar a volar programando en Lenguaje ensamblador? Pues lo siguiente: ¿QUÉ HAGO CON TODOS LOS RECURSOS QUE NECESITO? Aquí hago distinción sobre qué hacer, primero en Windows y acto seguido en Linux, como sigue: En Windows: 1. Ejecutamos el instalador (nasm-2.11.05-installer.exe, por ejemplo). Dejamos que se instale todo por defecto. Por ejemplo, dejen que sea creado un acceso directo en el escritorio ya que nos va ahorrar esfuerzo para hacer algo que explicare a continuación. 2. Una vez que está instalado recurrimos al acceso directo que había comentado o vamos a su carpeta respectiva carpeta en el menú de inicio. Lo que vamos a hacer aquí es que por medio de la opción Abrir la ubicación del archivo vamos a ubicarnos donde se encuentran todos los recursos de instalación. Esta carpeta la mantendremos abierta nos será útil unos pasos más adelante.
  • 4. Página 4 de 66 Materia: Lenguaje Ensamblador Clave: F1265 3. Se supone que todavía tenemos abierta la carpeta donde está instalado NASM, bueno lo siguiente es extraer allí el archivo al_al.zip que yo nombré alinker.zip los archivos tal y como se muestran NO deben ser extraídos en una carpeta dentro de la carpeta ..AppDataLocalnasm deben estar en la misma jerarquía. 4. Lo siguiente es copiar la ruta de instalación y agregarla a PATH en las variables de entorno de Windows. Ustedes ya saben cómo, nos quedaría más o menos así: 5. El paso 4 o punto cuatro es para ahorranos chamba y que nasm sea accesible desde cualquier parte de nuestro sistema operativo Windows. Lo que vamos a hacer ahora es que nasm y alinker se casen para ello haremos lo siguiente: 5.1. Escribir desde la consola (CMD) lo siguiente alink y le daremos Enter a todo (--Press Enter to continue--)
  • 5. Página 5 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Después de esto nos mandará fuera de ejecución de alink. Lo que sigue aquí mismo es verificar que se conserva la armonía con el depurador nativo de Windows para lo que escribiremos debug y después r damos Enter y luego salimos escribiendo q habiendo obtenido el stock de registros. La imagen siguiente muestra lo que comente. Nota: Para quienes trabajen con Windows x64 pueden con el DOSBox (antes mencionado) para ello pueden hay video donde explican acerca de él. Enlace exacto: https://www.youtube.com/watch?v=pMrh-ppGp1E además necesitarán el archivo debug.exe el cual lo subí a GoogleDrive junto con MASM en el siguiente enlace: https://drive.google.com/file/d/0BxC4ezWP4GyIeFp1T3pRanVQVFk/view?usp=sharing y como ya saben, usarlo con variables de entorno. 6. Ahora lo que hago es por pura vanidad, vamos con el archivo comprimido que descargamos que contiene al editor nano (nano-editor_2.2.6.zip) lo extraemos en una ubicación acorde a nuestro gusto (C:nano_2.2.6, por ejemplo) y lo agregamos a las variables de entorno. Y listo ya tenemos todo listo para empezar con nasm desde Windows.
  • 6. Página 6 de 66 Materia: Lenguaje Ensamblador Clave: F1265 En Linux: 1. Para instalar NASM en Linux hay dos vías una es por vía repositorio escribiendo sudo apt-get install nasm lo cual nos instalará una versión sumamente antigua y la otra es por medio de la compilación del archivo que descargamos (nasm-2.11.05.tar.gz). Si elegimos esta última debemos hacer lo siguiente. 1.1. Extraer el archivo en un directorio con privilegios root en /usr/local/src por ejemplo debemos conseguir que se nos cree la carpeta respectiva nasm-2.11.05 en mi caso, por ejemplo. Luego nos ubicaremos dentro de dicha carpeta. 1.2. Lo que sigue es abrir la terminal y navegar hasta la carpeta que tenemos abierta. Luego escribiremos sudo ./configure para ejecutar este script de unos 190 kb esperaremos mientras se lleva a cabo el proceso una vez terminado tipeamos make para que se compilen los archivos binarios de nasm, volvemos a esperar y ahora si a instalarlo con make install que por defecto manda la instalación a /usr/local/bin luego comprobamos que efectivamente tenemos instalado nasm como se ilustra en la siguiente imagen. Debo mencionar que las ubicaciones simbólicas indican que en nuestro sistema instalo correctamente a nasm.
  • 7. Página 7 de 66 Materia: Lenguaje Ensamblador Clave: F1265 1.3. Tenemos la opción de agregar herramientas que complementan a nasm para ello estando en /usr/local/src/nasm-2.11.05/rdoff desde terminal escribimos make rdf y luego make rdf_install 1.4 Por ultimo eliminamos los archivos archivos de nasm de la ubicación /usr/local/src/ pues ya no los necesitamos. Y listo ya tenemos todo listo para empezar con NASM desde Linux. Al parecer fue más rollo para Windows, disculpen... ¡A PROGRAMAR! Para saber cómo trabajar con nasm consulte la documentación donde antes mencione, ya sea en html o pdf. Para estudiar los fundamentos hay 3 fuentes que recomiendo: 1. Abre los Ojos al Ensamblador: http://www.abreojosensamblador.net/Productos/AOE/Index.html 2. Assembly in youtube: https://www.youtube.com/playlist?list=PL001102C2DF1D0CE9 3. Intel® 64 and IA-32 Architectures Software: http://www.intel.com/content/www/us/en/processors/architectures-software-developer- manuals.html 1. Hola mundo La finalidad de este primer programa es seguir la tradición y para explicar la manera de trabajar que consiste en editar un archivo .asm y compilarlo con nasm. Veamos cómo se hace: En Windows: Editamos nuestro archivo holawindows.asm desde nano. Una vez editado guardamos y nos volvemos a ubicar desde consola en el directorio desde el cual estamos trabajando con el código.
  • 8. Página 8 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Para compilarlo escribimos nasm holawindows.asm -o holawindows.[com, exe] en muestro caso exe con la instrucción de salida de nasm (-o). Después damos Enter, revisamos que efectivamente ha sido creado y lo mandamos a ejecutar escribiendo el nombre del archivo sin extensión para comprobar. Lo mismo pasaría si decidiéramos generar un ejecutable .com sólo que lo ejecutaríamos con un tercer archivo que es generado por el propio nasm. En Linux: Primero nos aseguramos que el directorio en el que vamos a trabajar esta con propiedades de lectura, escritura y ejecución (chmod 777). Entonces editamos nuestro archivo holalinux.asm desde nano. Una vez editado guardamos y nos volvemos a ubicar desde terminal en el directorio desde el cual estamos trabajando con el código. Para enlazar escribimos nasm -f elf holalinux.asm damos Enter y para ensamblar escribimos ld -s - o holalinux holalinux.o donde primero nos creará el script de ejecución y luego el archivo objeto binario. Después damos Enter, revisamos que efectivamente 2 archivos han sido creados y lo mandamos a ejecutar escribiendo ./holalinux el nombre del archivo sin extensión para comprobar.
  • 9. Página 9 de 66 Materia: Lenguaje Ensamblador Clave: F1265 CÓDIGO: holawindows.asm org 100h mov dx,string ; definimos la variable string mov ah,9 ; 9 es copiado en el registro ah int 21h ; colocamos una instrcción de interrupción mov ah,4Ch int 21h string db 'Hola, Mundo!',0Dh,0Ah,'$' ; 0Dh es el caracter de retornar, 0Ah es el pie de linea, el signo $ es para terminar la cadena holalinux.asm section .text global _start _start: mov eax,4 ; ID de llamada al sistema: sys_write - escribir mov ebx,1 ; descriptor de archivo para salida estandard mov ecx,string ; dirección de string mov edx,length ; string length int 80h ; llamada al sistema mov eax,1 ; ID de llamada al sistema: sys_exit - salida mov ebx,0 ; codigo 0 de salida: no error int 80h ; llamada al sistema section .data string: db 'Hola Mundo!',0Ah ; string de salida
  • 10. Página 10 de 66 Materia: Lenguaje Ensamblador Clave: F1265 length: equ 13 ; longitud del string 2. Plantilla básica Antes de empezar quiero hacer paréntesis. (Supongo que alrededor del 80% trabajará desde Windows así que desde ahora voy a continuar desde el entorno Windows). Esto con la finalidad de reducir el tamaño del documento con las demostraciones para ambos sistemas operativos. Ok… Este programa consiste en el esqueleto que tiene básicamente un programa en ensamblador haciendo uso de declaraciones, comentarios, funciones y constantes. Editamos nuestro archivo esqueleto.asm y guardamos. Este código realmente no es funcional y nuestro resultado es que manda como salida mensajes de error al momento de la compilación debido a que algunas instrucciones están incompletas, pues solo han sido colocadas en su respectivo lugar pero no se están manejando con su sintaxis correcta. En este caso es enter en la línea 12, push en la línea 13 y pop en la línea 17.
  • 11. Página 11 de 66 Materia: Lenguaje Ensamblador Clave: F1265 CÓDIGO: esqueleto.asm segment .data ; ; data inicializado ; segment .bss ; ; data unitilizado ; segment .text global _func _func: enter n,0 ; línea 12 push ; guardar registros línea 13 ; ; cuerpo de la funcion ; pop ; devolver registros línea 17 mov eax,0 ; retornar valor leave ret Otra forma de tener nuestra plantilla sería como sigue: esqueleto2.asm segment .data ; ; data inicializado ; segment .bss ; ; data unitilizado ; segment .text
  • 12. Página 12 de 66 Materia: Lenguaje Ensamblador Clave: F1265 global _func _func: push ebp ; si necesitamos que esta instrucción se ejecute antes mov ebp,esp ; copiamos ebp en esp sub esp,n ; sustituimos por enter push ; guardar registros ; ; cuerpo de la funcion ; pop ; devolver registros mov eax,0 ; retornar valor mov esp,ebp pop ebp ret ; devolvemos el valor de la rutina 3. Ensamblando y enlazando con C: ejemplo mcd En este programa veremos cómo podemos trabajar desde ensamblador con código fuente del lenguaje C. Para esto, el ejemplo consiste en encontrar el máximo común divisor con el modo sencillo, aquí editamos el archivo mcd.asm con nuestro respectivo código. Lo guardamos. Luego creamos nuestro código en C, en este caso lo nombré codigoprincipal.c en el cual solo se reciben y envían valores pues el algoritmo se ejecuta en código ensamblador. Lo guardamos.
  • 13. Página 13 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Lo que sigue es hacer el constructor del ensamblado y enlazado, aquí el truco es por medio de un archivo ejecutable por lotes el cual llamé construir.bat en el cual indicamos que sean limpiados los archivos de salida que hayamos generado previamente con erase, luego establecemos variables de recursos para el compilador Visual C/C++ (pues tengo instalado Visual Studio). Debo hacer énfasis en que la línea marca @set BIN=C:Program FilesMicrosoft Visual Studio 12.0VCbin para que nos funcione mejor la agreguemos al PATH en las variables de entorno, pues en esta ruta se encuentra el ejecutable cl.exe (compilador de optimización x86). Luego análogamente a la opción -o de nasm utilizamos -f para indicar que mande de salida ejecutable x86, luego utilizamos la opción --prefix más _ para el argumento dado para todas las variables globales o externos, como en C. Lo cual va de la mano con el compilador de optimización x86 que se encargará de codigoprincipal.c y mcd.obj, y guardamos. Acto seguido ejecutamos construir.bat desde consola damos Enter y esperamos a que el proceso termine, luego revisamos los archivos de salida creados.
  • 14. Página 14 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Por ultimo verificamos que nuestro ejecutable .exe si funcione. CÓDIGO: mcd.asm segment data segment bss
  • 15. Página 15 de 66 Materia: Lenguaje Ensamblador Clave: F1265 segment text global mcd mcd: push ebp mov ebp,esp mov eax,[ebp+8] ; x mov ebx,[ebp+12] ; y looptop: cmp eax,0 ; if (x == 0) hemos terminado je goback cmp eax,ebx ; hacer que cierto valor x sea un numero mas grande jge modulo xchg eax,ebx ; intercambiar x & y modulo: cdq ; setup para division idiv ebx ; dividir edxeax por ebx mov eax,edx ; el residuo esta en edx jmp looptop goback: mov eax,ebx ; retornar y mov esp,ebp pop ebp ret codigoprincipal.c #include <stdio.h> int mcd(int a,int b); int main() { int result; int a; int b;
  • 16. Página 16 de 66 Materia: Lenguaje Ensamblador Clave: F1265 a = 46; b = 90; printf("%d y %d tienen un mcd de %dn",a,b,mcd(a,b)); a = 9863; b = 41272; printf("%d y %d tiene un mcd de %dn",a,b,mcd(a,b)); } construir.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib @set BIN=C:Program FilesMicrosoft Visual Studio 12.0VCbin nasm -f win32 mcd.asm --prefix _ cl codigoprincipal.c mcd.obj 4. Generando números aleatorios Este programa consiste en usar el algoritmo inorder para generar un número entero aleatorio entre un rango especificado ya sea entre números positivos y negativos. Suponemos que con los ejemplos anteriores ya tenemos claro cuál es nuestro patrón de producción a código final, por lo que no entraremos en tanto detalle redundando en cosas que debemos hacer. Ok… editamos nuestro código en C que llamaremos codigo_random.c, en ensamblador enteros_random.asm y nuestro script de builder construir_random.bat y vemos nuestro resultado.
  • 17. Página 17 de 66 Materia: Lenguaje Ensamblador Clave: F1265 CÓDIGO: enteros_random.asm segment .data segment .bss segment .text global enterorandom ; definimos nuestra variable global enterorandom: push ebp mov ebp,esp mov eax,[ebp+8] ; primer argumento cmp eax,[ebp+12] ; asegurarse de que el primer argumento es menor jl inorder xchg eax,[ebp+12] ; intercambiar primero y segundo mov [ebp+8],eax inorder: ; creamos la funcion inorder entre preorder y postorder rdtsc ; leer contador de marca de tiempo shr eax,2 mov ebx,[ebp+12] ; el valor más grande add ebx,1 ; sumar uno sub ebx,[ebp+8] ; subtracción del valor delta cdq ; limpiar edx idiv ebx ; dividir edxeax por ebx add edx,[ebp+8] goback: mov eax,edx mov esp,ebp pop ebp ret
  • 18. Página 18 de 66 Materia: Lenguaje Ensamblador Clave: F1265 codigo_random.c #include <stdio.h> int enterorandom(int menor,int mayor); int main() { int i; int a; int b; a = 1; b = 18; printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b)); a = 5500; b = 100; printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b)); a = -20; b = 20; printf("Entero aleatorio entre %d y %d: %dn",a,b,enterorandom(a,b)); } construir_random.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 enteros_random.asm --prefix _ cl codigo_random.c enteros_random.obj
  • 19. Página 19 de 66 Materia: Lenguaje Ensamblador Clave: F1265 5. Encontrando números primos Aquí trabajamos con el manejo de entrada y salida de datos definidos por el usuario por medio de un programa que se encarga de encontrar los números primos entre una rango que debe ser especificado al inicio de ejecución. Para esto se codificaron los archivos codigo_primo.c, primo.asm, entrada.asm, salida.asm y construir_primo.bat, nuestro resultado es como se muestra en la imagen. CÓDIGO: primo.asm segment .data inferior_prompt: db "Valor inferior a probar: ",0 superior_prompt: db "Valor superior a probar: ",0 newline: db 10,0 segment .bss inferior: resd 1 superior: resd 1 recorrer: resd 1 factor: resd 1 segment .text extern out_integer extern in_integer extern out_string global encontrar_primos encontrar_primos:
  • 20. Página 20 de 66 Materia: Lenguaje Ensamblador Clave: F1265 enter 0,0 pushad pushfd ; pedir límites superior e inferior push dword inferior_prompt call in_integer pop ebx mov [inferior],eax or eax,0x00000001 mov [recorrer],eax push dword superior_prompt call in_integer pop ebx mov [superior],eax mov dword [factor],2 ; parte superior del bucle de prueba factortest: mov eax,[factor] ; prueba para el factor mas grande imul eax,eax cmp [recorrer],eax jl encontrar mov eax,[recorrer] ; prueba para el acarreo de división mov ebx,[factor] cdq idiv ebx cmp edx,0 je siguiente add dword [factor],1 ; empujar factor y ciclar jmp factortest
  • 21. Página 21 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ; encontrar un primo encontrar: push dword [recorrer] call out_integer pop eax push dword newline call out_string pop eax ; pasar al siguiente primo candidato siguiente: mov eax,[recorrer] add eax,2 cmp eax,[superior] jg terminado mov [recorrer],eax mov dword [factor],2 jmp factortest terminado: popfd popad mov eax,0 leave ret codigo_primo.c void encontrar_primos(void); int main() { encontrar_primos(); }
  • 22. Página 22 de 66 Materia: Lenguaje Ensamblador Clave: F1265 entrada.asm segment .data segment .bss char_hold: resd 1 str_hold: resb 20 str_len: equ $-str_hold-1 value: resd 1 segment .text extern out_string extern getchar global in_char in_char: enter 0,0 pushad pushfd push dword [ebp+8] call out_string pop eax mov byte [char_hold],' ' call getchar cmp eax,10 jz .in_char_finish mov [char_hold],al
  • 23. Página 23 de 66 Materia: Lenguaje Ensamblador Clave: F1265 .in_char_flush: call getchar cmp eax,10 jnz .in_char_flush .in_char_finish: popfd popad mov al,[char_hold] leave ret global in_string in_string: enter 0,0 pushad pushfd push dword [ebp+8] call out_string pop eax mov ebx,str_hold ; dirección para almacenar cadena mov byte [ebx],0 mov ecx,str_len ; longitud máxima de la cadena .in_string_loop: call getchar
  • 24. Página 24 de 66 Materia: Lenguaje Ensamblador Clave: F1265 cmp eax,10 jz .in_string_finish mov [ebx],al add ebx,1 mov byte [ebx],0 sub ecx,1 jnz .in_string_loop .in_string_flush: call getchar cmp eax,10 jnz .in_string_flush .in_string_finish: popfd popad mov eax,str_hold leave ret global in_integer in_integer: enter 0,0 pushad pushfd
  • 25. Página 25 de 66 Materia: Lenguaje Ensamblador Clave: F1265 push dword [ebp+8] call in_string pop ebx xor ecx,ecx .in_integer_loop: xor ebx,ebx mov bl,[eax] cmp bl,0x30 jl .in_integer_finish cmp bl,0x39 jg .in_integer_finish sub ebx,0x30 mov edx,ecx shl edx,1 shl ecx,3 add ecx,edx add ecx,ebx add eax,1 jmp .in_integer_loop .in_integer_finish: mov [value],ecx popfd popad mov eax,[value] leave
  • 26. Página 26 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ret salida.asm %define CF_BIT 0x00000001 %define PF_BIT 0x00000004 %define AF_BIT 0x00000010 %define ZF_BIT 0x00000040 %define SF_BIT 0x00000080 %define DF_BIT 0x00000400 %define OF_BIT 0x00000800 ; El segmento de datos ;;;;;;;;;;;;;;;; segment .data string_fmt: db "%s",0 integer_fmt: db "%d",0 flag_string: db "flags: ",0 cf_string: db "CF ",0 pf_string: db "PF ",0 af_string: db "AF ",0 zf_string: db "ZF ",0 sf_string: db "SF ",0 df_string: db "DF ",0 of_string: db "OF ",0 newline_string: db 10,0 hex_reg_fmt: db "eax: 0x%.8X ebx: 0x%.8X ecx: 0x%.8X edx: 0x%.8X",10 db 0
  • 27. Página 27 de 66 Materia: Lenguaje Ensamblador Clave: F1265 dec_reg_fmt: db "eax: %d ebx: %d ecx: %d edx: %d",10 db 0 ; El segmento bss ;;;;;;;;;;;;;;;; segment .bss flags: resd 1 ; El segmento de texto ;;;;;;;;;;;;;;;; segment .text extern printf global out_string out_string: enter 0,0 pushad pushfd push dword [ebp+8] push dword string_fmt call printf pop ecx pop ecx popfd popad leave ret global out_flags
  • 28. Página 28 de 66 Materia: Lenguaje Ensamblador Clave: F1265 out_flags: enter 0,0 pushad pushfd push dword flag_string call out_string pop eax mov eax,[esp] ; obtener una copia de las banderas mov [flags],eax ; La bandera de acarreo (CF) mov eax,[flags] test eax,CF_BIT jz cf_not push cf_string call out_string pop eax cf_not: ; La bandera de paridad (PF) mov eax,[flags] test eax,PF_BIT jz pf_not push pf_string call out_string pop eax pf_not:
  • 29. Página 29 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ; La bandera de acarreo auxiliar mov eax,[flags] test eax,AF_BIT jz af_not push af_string call out_string pop eax af_not: ; La bandera de cero mov eax,[flags] test eax,ZF_BIT jz zf_not push zf_string call out_string pop eax zf_not: ; La bandera de signo mov eax,[flags] test eax,SF_BIT jz sf_not push sf_string call out_string pop eax sf_not: ; La bandera de dirección mov eax,[flags] test eax,DF_BIT
  • 30. Página 30 de 66 Materia: Lenguaje Ensamblador Clave: F1265 jz df_not push df_string call out_string pop eax df_not: ; La bandera de desbordamiento mov eax,[flags] test eax,OF_BIT jz of_not push of_string call out_string pop eax of_not: ; Un salto de línea push dword newline_string call out_string pop eax popfd popad leave ret ; ---------------------------- global out_hex_registers out_hex_registers: enter 0,0
  • 31. Página 31 de 66 Materia: Lenguaje Ensamblador Clave: F1265 pushad pushfd push edx push ecx push ebx push eax push dword hex_reg_fmt call printf add esp,20 popfd popad leave ret global out_integer out_integer: enter 0,0 pushad pushfd push dword [ebp+8] push dword integer_fmt call printf pop ecx pop ecx
  • 32. Página 32 de 66 Materia: Lenguaje Ensamblador Clave: F1265 popfd popad leave ret global out_dec_registers out_dec_registers: enter 0,0 pushad pushfd push edx push ecx push ebx push eax push dword dec_reg_fmt call printf add esp,20 popfd popad leave ret construir_primo.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude
  • 33. Página 33 de 66 Materia: Lenguaje Ensamblador Clave: F1265 @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 primo.asm --prefix _ nasm -f win32 entrada.asm --prefix _ nasm -f win32 salida.asm --prefix _ cl codigo_primo.c primo.obj entrada.obj salida.obj Además, anexo el script constructor para Linux (por si las dudas). Para los Linuxeros. construir_primo_linux nasm -f elf primo.asm nasm -f elf entrada.asm nasm -f elf salida.asm gcc codigo_primo.c primo.o entrada.o salida.o -o codigo_primo 6. Manipulación de bits: desplazando y alternando Este programa es una colección de métodos para practicar con las variantes que podemos codificar para mover bits con la bandera de acarreo (CF, con los 16 bits) tanto a la derecha como a la izquierda. Para esto, se ha definido el archivo mover.asm que es la colección de métodos, los archivos: aritmetica_izquierda.c, aritmetica_derecha.c, logica_izquierda.c, logica_derecha.c, alternar_izquierda.c, alternar_derecha.c, acarreo_alternar_izquierda.c y acarreo_alternar_derecha.c para llamar cada método por separado. Reutilizamos el archivo con el código de salida.asm para no tener problemas con los caracteres de salida y mostrar.asm de donde invocamos la función encargada de trabajar con las cadenas de bits a mostrar. Para compilarlo reutilizamos el constructor del ejemplo anterior y lo adaptamos a los archivos de código creados para la manipulación de bits, en nuestro caso podemos nombrarlo construir_mover_bits.bat, y una vez creados nuestros ejecutables probamos uno por uno para ver el resultado por cada método.
  • 34. Página 34 de 66 Materia: Lenguaje Ensamblador Clave: F1265 CÓDIGO: mover.asm segment .data segment .bss segment .text extern mostrar_ax global logica_izquierda logica_izquierda: enter 0,0 pushad mov ax,0x8002 call mostrar_ax shl ax,1 call mostrar_ax shl ax,1 call mostrar_ax popad leave ret
  • 35. Página 35 de 66 Materia: Lenguaje Ensamblador Clave: F1265 global logica_derecha logica_derecha: enter 0,0 pushad mov ax,0x8002 call mostrar_ax shr ax,1 call mostrar_ax shr ax,1 call mostrar_ax popad leave ret global aritmetica_izquierda aritmetica_izquierda: enter 0,0 pushad mov ax,0x8002 call mostrar_ax sal ax,1 call mostrar_ax sal ax,1 call mostrar_ax popad leave ret global aritmetica_derecha aritmetica_derecha:
  • 36. Página 36 de 66 Materia: Lenguaje Ensamblador Clave: F1265 enter 0,0 pushad mov ax,0x8002 call mostrar_ax sar ax,1 call mostrar_ax sar ax,1 call mostrar_ax popad leave ret global alternar_izquierda alternar_izquierda: enter 0,0 pushad mov ax,0x8002 call mostrar_ax rol ax,1 call mostrar_ax rol ax,1 call mostrar_ax popad leave ret global alternar_derecha alternar_derecha: enter 0,0 pushad
  • 37. Página 37 de 66 Materia: Lenguaje Ensamblador Clave: F1265 mov ax,0x8002 call mostrar_ax ror ax,1 call mostrar_ax ror ax,1 call mostrar_ax popad leave ret global acarreo_alternar_izquierda acarreo_alternar_izquierda: enter 0,0 pushad mov ax,0x8002 call mostrar_ax rcl ax,1 call mostrar_ax rcl ax,1 call mostrar_ax popad leave ret global acarreo_alternar_derecha acarreo_alternar_derecha: enter 0,0 pushad mov ax,0x8002
  • 38. Página 38 de 66 Materia: Lenguaje Ensamblador Clave: F1265 call mostrar_ax rcr ax,1 call mostrar_ax rcr ax,1 call mostrar_ax rcr ax,1 call mostrar_ax popad leave ret aritmetica_izquierda.c #include <stdio.h> void aritmetica_izquierda(void); int main() { aritmetica_izquierda(); } aritmetica_derecha.c #include <stdio.h> void aritmetica_derecha(void); int main() { aritmetica_derecha(); } logica_izquierda.c #include <stdio.h>
  • 39. Página 39 de 66 Materia: Lenguaje Ensamblador Clave: F1265 void logica_izquierda(void); int main() { logica_izquierda(); } logica_derecha.c #include <stdio.h> void logica_derecha(void); int main() { logica_derecha(); } alternar_izquierda.c #include <stdio.h> void alternar_izquierda(void); int main() { alternar_izquierda(); } alternar_derecha.c #include <stdio.h> void alternar_derecha(void); int main() {
  • 40. Página 40 de 66 Materia: Lenguaje Ensamblador Clave: F1265 alternar_derecha(); } acarreo_alternar_izquierda.c #include <stdio.h> void acarreo_alternar_izquierda(void); int main() { acarreo_alternar_izquierda(); } acarreo_alternar_derecha.c #include <stdio.h> void acarreo_alternar_derecha(void); int main() { acarreo_alternar_derecha(); } salida.asm %define CF_BIT 0x00000001 %define PF_BIT 0x00000004 %define AF_BIT 0x00000010 %define ZF_BIT 0x00000040 %define SF_BIT 0x00000080 %define DF_BIT 0x00000400 %define OF_BIT 0x00000800 ; El segmento de datos ;;;;;;;;;;;;;;;; segment .data
  • 41. Página 41 de 66 Materia: Lenguaje Ensamblador Clave: F1265 string_fmt: db "%s",0 integer_fmt: db "%d",0 flag_string: db "flags: ",0 cf_string: db "CF ",0 pf_string: db "PF ",0 af_string: db "AF ",0 zf_string: db "ZF ",0 sf_string: db "SF ",0 df_string: db "DF ",0 of_string: db "OF ",0 newline_string: db 10,0 hex_reg_fmt: db "eax: 0x%.8X ebx: 0x%.8X ecx: 0x%.8X edx: 0x%.8X",10 db 0 dec_reg_fmt: db "eax: %d ebx: %d ecx: %d edx: %d",10 db 0 ; El segmento bss ;;;;;;;;;;;;;;;; segment .bss flags: resd 1 ; El segmento de texto ;;;;;;;;;;;;;;;; segment .text extern printf global out_string out_string: enter 0,0 pushad pushfd push dword [ebp+8] push dword string_fmt call printf
  • 42. Página 42 de 66 Materia: Lenguaje Ensamblador Clave: F1265 pop ecx pop ecx popfd popad leave ret global out_flags out_flags: enter 0,0 pushad pushfd push dword flag_string call out_string pop eax mov eax,[esp] ; obtener una copia de las banderas mov [flags],eax ; La bandera de acarreo (CF) mov eax,[flags] test eax,CF_BIT jz cf_not push cf_string call out_string pop eax cf_not: ; La bandera de paridad (PF) mov eax,[flags] test eax,PF_BIT jz pf_not push pf_string call out_string
  • 43. Página 43 de 66 Materia: Lenguaje Ensamblador Clave: F1265 pop eax pf_not: ; La bandera de acarreo auxiliar mov eax,[flags] test eax,AF_BIT jz af_not push af_string call out_string pop eax af_not: ; La bandera de cero mov eax,[flags] test eax,ZF_BIT jz zf_not push zf_string call out_string pop eax zf_not: ; La bandera de signo mov eax,[flags] test eax,SF_BIT jz sf_not push sf_string call out_string pop eax sf_not: ; La bandera de dirección mov eax,[flags] test eax,DF_BIT jz df_not push df_string call out_string pop eax df_not:
  • 44. Página 44 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ; La bandera de desbordamiento mov eax,[flags] test eax,OF_BIT jz of_not push of_string call out_string pop eax of_not: ; Un salto de línea push dword newline_string call out_string pop eax popfd popad leave ret ; ---------------------------- global out_hex_registers out_hex_registers: enter 0,0 pushad pushfd push edx push ecx push ebx push eax push dword hex_reg_fmt call printf add esp,20 popfd
  • 45. Página 45 de 66 Materia: Lenguaje Ensamblador Clave: F1265 popad leave ret global out_integer out_integer: enter 0,0 pushad pushfd push dword [ebp+8] push dword integer_fmt call printf pop ecx pop ecx popfd popad leave ret global out_dec_registers out_dec_registers: enter 0,0 pushad pushfd push edx push ecx push ebx push eax push dword dec_reg_fmt call printf add esp,20
  • 46. Página 46 de 66 Materia: Lenguaje Ensamblador Clave: F1265 popfd popad leave ret mostrar.asm segment .data string_ax: db " " db " CF=" string_cf: db 0,10,0 segment .bss segment .text extern out_string global mostrar_ax mostrar_ax: enter 0,0 pushad pushfd mov byte [string_cf],'1' jc acarreo mov byte [string_cf],'0' acarreo: mov ebx,0 looptop: rol ax,1 jc uno mov byte [string_ax+ebx],'0' jmp siguiente uno: mov byte [string_ax+ebx],'1'
  • 47. Página 47 de 66 Materia: Lenguaje Ensamblador Clave: F1265 siguiente: inc ebx cmp ebx,16 jne looptop push string_ax call out_string pop ebx popfd popad leave ret construir_mover_bits.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 mostrar.asm --prefix _ nasm -f win32 salida.asm --prefix _ nasm -f win32 mover.asm --prefix _ cl logica_izquierda.c mostrar.obj salida.obj mover.obj cl logica_derecha.c mostrar.obj salida.obj mover.obj cl aritmetica_izquierda.c mostrar.obj salida.obj mover.obj cl aritmetica_derecha.c mostrar.obj salida.obj mover.obj cl alternar_izquierda.c mostrar.obj salida.obj mover.obj cl alternar_derecha.c mostrar.obj salida.obj mover.obj cl acarreo_alternar_izquierda.c mostrar.obj salida.obj mover.obj cl acarreo_alternar_derecha.c mostrar.obj salida.obj mover.obj Para construirlo en Linux aplicaríamos la misma lógica, y la sintaxis del ejemplo anterior.
  • 48. Página 48 de 66 Materia: Lenguaje Ensamblador Clave: F1265 7. Operaciones booleanas: and, or, xor, not En este programa se implementan las operaciones booleanas and, or, xor y not, codificando funciones específicas para cada tipo de operación, accediendo a las banderas de paridad, zero y signo. Teniendo esta idea necesitamos código de prueba para mostrar los bits originales sobre los cuales se harán las operaciones. Entonces hacemos lo siguiente. Como en el ejemplo anterior, creamos en este caso nuestra colección de las funciones que realizan cada tipo de operación booleana y anexamente nuestro código de prueba que genera los bits originales que se utilizan como prueba con las banderas. Nuestros recursos son modos_boolean.asm que es nuestra colección de funciones, los archivos de código C que son: and.c, or.c, xor.c, not.c y test.c que implementan cada función, reutilizamos mostrar.asm, salida.asm y nuestro constructor para nuestros recursos de código como en el ejemplo anterior. Ahora vemos nuestro resultado. CÓDIGO: modos_boolean.asm segment .data segment .bss segment .text Prueba original con las banderas. Implementando las funciones.
  • 49. Página 49 de 66 Materia: Lenguaje Ensamblador Clave: F1265 extern showal extern out_flags ; funcion operacion and global andbits andbits: enter 0,0 pushad mov al,11110000b call showal mov al,00110011b call showal mov al,00110011b and al,11110000b call showal popad leave ret ; funcion operacion or global orbits orbits: enter 0,0 pushad mov al,11110000b call showal mov al,00110011b call showal mov al,00110011b or al,11110000b call showal popad
  • 50. Página 50 de 66 Materia: Lenguaje Ensamblador Clave: F1265 leave ret ; funcion operacion xor global xorbits xorbits: enter 0,0 pushad mov al,11110000b call showal mov al,00110011b call showal mov al,00110011b xor al,11110000b call showal popad leave ret ; funcion operacion not global notbits notbits: enter 0,0 pushad mov al,00110011b call showal mov al,00110011b not al call showal popad leave ret
  • 51. Página 51 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ; funcion de prueba, bits originales global testbits testbits: enter 0,0 pushad mov al,11001100b call showal mov al,00110011b call showal mov al,00110011b test al,11001100b call out_flags mov al,11100011b call showal mov al,11101100b call showal mov al,11100011b test al,11101100b call out_flags popad leave ret test.c #include <stdio.h> void testbits(void); int main(){ testbits(); }
  • 52. Página 52 de 66 Materia: Lenguaje Ensamblador Clave: F1265 and.c #include <stdio.h> void andbits(void); int main() { andbits(); } or.c #include <stdio.h> void orbits(void); int main(){ orbits(); } xor.c #include <stdio.h> void xorbits(void); int main(){ xorbits(); } not.c #include <stdio.h> void notbits(void); int main(){ notbits(); }
  • 53. Página 53 de 66 Materia: Lenguaje Ensamblador Clave: F1265 salida.asm “reutilizamos el del ejemplo anterior” mostrar.asm “reutilizamos el del ejemplo anterior” construir_modos_boolean.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 mostrar.asm --prefix _ nasm -f win32 salida.asm --prefix _ nasm -f win32 modos_boolean.asm --prefix _ cl and.c modos_boolean.obj mostrar.obj salida.obj cl or.c modos_boolean.obj mostrar.obj salida.obj cl xor.c modos_boolean.obj mostrar.obj salida.obj cl not.c modos_boolean.obj mostrar.obj salida.obj cl test.c modos_boolean.obj mostrar.obj salida.obj y para Linux. construir_modos_boolean_linux rm -f *.o rm -f and rm -f or rm -f xor rm -f not
  • 54. Página 54 de 66 Materia: Lenguaje Ensamblador Clave: F1265 rm -f test nasm -f elf salida.asm nasm -f elf mostrar.asm nasm -f elf modos_boolean.asm gcc and.c salida.o modos_boolean.o mostrar.o -o and gcc or.c salida.o modos_boolean.o mostrar.o -o or gcc xor.c salida.o modos_boolean.o mostrar.o -o xor gcc not.c salida.o modos_boolean.o mostrar.o -o not gcc test.c salida.o modos_boolean.o mostrar.o -o test 8. Elección sin árbol: escoger número más grande En este programa hacemos uso del algoritmo de búsqueda de una pasada para encontrar el número más grandes entre dos valores ingresados al inicio de ejecución (sin importar orden y tamaño de número). En este ejemplo podemos revisar cómo trabajar con simples estructuras de control para producir resultados en base a valores de entrada. Para esto codificamos escoger.asm que contiene el algoritmo y las variables, codigo_escoger.c para utilizar nuestra función, enlazar y compilar nuestro ejecutable, reutilizamos entrada.asm y salida.asm de ejemplos anteriores y adaptamos nuestro constructor (construir_escoger.bat) de acuerdo a nuestros recursos de código. Nuestro resultado es el siguiente. CÓDIGO: escoger.asm segment .data
  • 55. Página 55 de 66 Materia: Lenguaje Ensamblador Clave: F1265 ask1: db "Ingrese primer numero: ",0 ask2: db "Ingrese segundo numero: ",0 tell db "El numero mas grande es: ",0 newline db 10,0 segment .bss valor1: resd 1 segment .text extern in_integer extern out_integer extern out_string global escoger escoger: enter 0,0 push dword ask1 call in_integer pop ebx mov [valor1],eax push dword ask2 call in_integer pop ebx xor ebx,ebx ; zero ebx cmp eax,[valor1] ; comparar los dos valores setg bl ; establecer bl=1 si valor2 > valor1, sino cero not ebx ; cumplimiento del primero
  • 56. Página 56 de 66 Materia: Lenguaje Ensamblador Clave: F1265 inc ebx ; cumplimiento del segundo mov ecx,ebx ; copiar en ecx and ecx,eax ; ecx es: o segundo valor, o cero not ebx ; ebx es cero o todos and ebx,[valor1] ; ebx es cero o primer de valor or ecx,ebx ; ecx es ya sea primer o segundo valor push dword tell call out_string pop ebx push ecx call out_integer pop ebx push dword newline call out_string pop ebx leave ret codigo_escoger.c #include <stdio.h> void escoger(void); int main() { escoger(); } entrada.asm
  • 57. Página 57 de 66 Materia: Lenguaje Ensamblador Clave: F1265 “reutilizamos de un ejemplo anterior” salida.asm “reutilizamos el del ejemplo anterior” construir_escoger.c erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 escoger.asm --prefix _ nasm -f win32 salida.asm --prefix _ nasm -f win32 entrada.asm --prefix _ cl codigo_escoger.c entrada.obj salida.obj escoger.obj Y para Linux, pues ya saben... 9. Arreglos: definiendo y manejando direcciones Este programa depende más de código C que de ensamblador. En este último solo definimos el manejo de las direcciones en memoria y en lenguaje C codificamos el comportamiento de los arreglos con valores preestablecidos y la orden de salida. Para que se perciba como podemos trabajar con ellos se han creado 2 variantes la primera es un arreglo simple donde multiplicamos sus valores y la segunda es un arreglo multidimensional donde los valores son ordenados por el método bubble sort, aunque en la salida no se pueda apreciar en primera instancia. Versión 1: Aquí los recursos de código son codigo_por_cuatro.c, por_cuatro.asm y construir_arreglos.bat con lo cual obtendremos el siguiente resultado.
  • 58. Página 58 de 66 Materia: Lenguaje Ensamblador Clave: F1265 Versión 2: Aquí los recursos de código son codigo_ordenar.c, ordenar.asm y construir_arreglos.bat con lo cual obtendremos el siguiente resultado. Aquí los valores de cada posición han sido ordenados por el método bubble sort (ordenamiento burbuja). CÓDIGO: codigo_por_cuatro.c #include <stdio.h> void por_cuatro(int tamanio,int arr[]); int main() { int i; int tamanio=10; int array[10]; for(i=0; i<tamanio; i++) { array[i] = i; printf("%d ",array[i]); } printf("n"); por_cuatro(tamanio,array); for(i=0; i<tamanio; i++) { printf("%d ",array[i]); }
  • 59. Página 59 de 66 Materia: Lenguaje Ensamblador Clave: F1265 printf("n"); } por_cuatro.asm segment .data segment .bss segment .text global por_cuatro por_cuatro: push ebp mov ebp,esp mov ebx,[ebp+12] ; direccion del arreglo mov ecx,[ebp+8] ; tamaño del arreglo top: mov eax,[ebx] shl eax,2 mov [ebx],eax add ebx,4 loop top leave ret codigo_ordenar.c #include <stdio.h> void a_ordenar(int tamanio,int arr[]); int array[] = { 5,32,87,4,92,11,34,3,84,60,17 }; int main() {
  • 60. Página 60 de 66 Materia: Lenguaje Ensamblador Clave: F1265 int i; int tamanio = sizeof(array) / sizeof(int); for(i=0; i<tamanio; i++) { printf("%d ",array[i]); } printf("n"); a_ordenar(tamanio,array); for(i=0; i<tamanio; i++) { printf("%d ",array[i]); } printf("n"); } ordenar.asm segment .data segment .bss segment .text global a_ordenar a_ordenar: push ebp mov ebp,esp reiniciar: mov ebx,[ebp+12] ; direccion del arreglo mov ecx,[ebp+8] ; tamaño del arreglo sub ecx,1 top: mov eax,[ebx] cmp eax,[ebx+4]
  • 61. Página 61 de 66 Materia: Lenguaje Ensamblador Clave: F1265 jle noswap xchg eax,[ebx+4] mov [ebx],eax jmp reiniciar noswap: add ebx,4 loop top leave ret construir_arreglos.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 por_cuatro.asm --prefix _ nasm -f win32 ordenar.asm --prefix _ cl codigo_por_cuatro.c por_cuatro.obj cl codigo_ordenar.c ordenar.obj 10. Punto flotante: ejemplo ecuación cuadrática En este programa tratamos con números de punto flotante para que de acuerdo a este tipo de valor llevemos a cabo instrucciones condicionales. El ejemplo elegido es el cálculo de la ecuación cuadrática donde una solución puede ser positiva y otra negativa, enteras o de punto flotante, infinito negativo e infinito positivo, etc. Digamos que, tratamos con una cuestión práctica donde se requiere exactitud en los cálculos. Para este caso los recursos de código creados son codigo_cuadratica.c, cuadratica.asm y construir_cuadratica.bat, y el comportamiento que obtenemos es el siguiente.
  • 62. Página 62 de 66 Materia: Lenguaje Ensamblador Clave: F1265 CÓDIGO: cuadratica.asm %define a qword [ebp+8] %define b qword [ebp+16] %define c qword [ebp+24] %define solucion1 dword [ebp+32] %define solucion2 dword [ebp+36] %define rad qword [ebp-8] %define recip_2a qword [ebp-16] segment .data menoscuatro: dw -4 segment .bss segment .text global cuadratica cuadratica: push ebp mov ebp,esp sub esp,16 ; dos espacios de trabajo double
  • 63. Página 63 de 66 Materia: Lenguaje Ensamblador Clave: F1265 push ebx fild word [menoscuatro] ; st: -4 fld a ; st: a, -4 fld c ; st: c, a, -4 fmulp st1 ; st: a*c, -4 fmulp st1 ; st: -4*a*c fld b ; st: b, -4*a*c fld b ; st: b, b, -4*a*c fmulp st1 ; st: b*b, -4*a*c faddp st1 ; st: b*b - 4*a*c ftst ; comparar st0 a 0 fstsw ax ; ax = palabra de estado sahf ; banderas = ah jb no_solucion_real fsqrt ; st: sqrt(b*b - 4*a*c) fstp rad ; st: vacio, y radical almacenado fld1 ; st: 1 fld a ; st: a, 1 fscale ; st: 2*a, 1 fdivp st1 ; st: 1/(2*a) fst recip_2a ; st: 1/(2*a) fld b ; st: b, 1/(2*a) fld rad ; st: rad , b, 1/(2*a) fsubrp st1 ; st: rad - b, 1/(2*a) fmulp st1 ; st: (-b + rad )/(2*a) mov ebx,solucion1 fstp qword [ebx] ; resultado en solucion1 fld b ; st: b fld rad ; st: rad , b fchs ; st: -rad , b fsubrp st1 ; st: -rad - b fmul recip_2a ; st: (-rad - b)/(2*a)
  • 64. Página 64 de 66 Materia: Lenguaje Ensamblador Clave: F1265 mov ebx,solucion2 fstp qword [ebx] ; resultado en solucion2 mov eax,1 ; retornar valor jmp quit no_solucion_real: mov eax,0 quit: pop ebx mov esp,ebp pop ebp ret codigo_cuadratica.c #include <stdio.h> int cuadratica(double,double,double,double *,double *); int main() { double a; double b; double c; double solucion1; double solucion2; int cond; do { printf("na: "); scanf("%lf",&a); printf("b: "); scanf("%lf",&b); printf("c: ");
  • 65. Página 65 de 66 Materia: Lenguaje Ensamblador Clave: F1265 scanf("%lf",&c); cond = cuadratica(a,b,c,&solucion1,&solucion2); if(cond == 0) { printf("Sin solucion real.n"); } else { printf("%g and %gn",solucion1,solucion2); } } while(1); } construir_cuadratica.bat erase *.obj erase *.exe @set INCLUDE=C:Program FilesMicrosoft Visual Studio 12.0VCinclude @set LIB=C:Program FilesMicrosoft Visual Studio 12.0VClib;C:Program FilesMicrosoft SDKsWindowsv7.1ALib nasm -f win32 cuadratica.asm --prefix _ cl codigo_cuadratica.c cuadratica.obj FUENTES ANEXAS: Las siguientes fuentes de información hacen referencia a documentos (e-books) publicados que son de utilidad para estudiar la programación en lenguaje ensamblador, unas son mejores que otras pero todas se complementan. 1. Richard Blum. Professional Assembly Language. Wiley Publishing, Inc. 2. Peter Abel. Lenguaje ensamblador y programación para IBM PC y compatibles. Pearson Education, Inc. 3. Randall Hyde. The Art Of Assembly Language. No Starch Press, Inc. 4. Jeff Duntemann. Assembly Language Step-by-Step: Programming with Linux. Wiley Publishing, Inc.
  • 66. Página 66 de 66 Materia: Lenguaje Ensamblador Clave: F1265 5. Kip R. Irvine. Lenguaje ensamblador para computadoras basadas en Intel. Pearson Education, Inc. 6. Joseph Cavanagh. X86 Assembly Language and C Fundamentals. CRC Press by Taylor & Francis Group