Lenguaje_Ensamblador_0_a_100-libre.pdf

66
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

Transcript of Lenguaje_Ensamblador_0_a_100-libre.pdf

  • Lenguaje Ensamblador: Guia prctica ...............................................................................................2

    QU NECESITO? ...............................................................................................................................2

    QU HAGO CON TODOS LOS RECURSOS QUE NECESITO? ..............................................................3

    A PROGRAMAR! ...............................................................................................................................7

    1. Hola mundo ...............................................................................................................................7

    2. Plantilla bsica .........................................................................................................................10

    3. Ensamblando y enlazando con C: ejemplo mcd ......................................................................12

    4. Generando nmeros aleatorios...............................................................................................16

    5. Encontrando nmeros primos .................................................................................................19

    6. Manipulacin de bits: desplazando y alternando ...................................................................33

    7. Operaciones booleanas: and, or, xor, not ...............................................................................48

    8. Eleccin sin rbol: escoger nmero ms grande .....................................................................54

    9. Arreglos: definiendo y manejando direcciones.......................................................................57

    10. Punto flotante: ejemplo ecuacin cuadrtica .......................................................................61

    FUENTES ANEXAS: ...........................................................................................................................65

  • Pgina 2 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    Lenguaje Ensamblador: Guia prctica

    Jess Antonio Ferrer Snchez

    Para programar en lenguaje ensamblador escog la especificacin 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 Cul es la az? La espuesta es ue el popio oe lo die Netide Assele, es decir, existe una comunidad que mantiene actualizada documentacin y herramientas para

    programar en lenguaje ensamblador.

    Bueo aos a la oa, paa epeza eesitaos visitar el sitio Web donde se encuentra los ms importante que necesitaremos http://www.nasm.us/, hecho esto la siguiente cuestin es Qu

    vamos a utilizar de all? Pues lo siguiente:

    QU NECESITO? 1. La documentacin, que est aqu:

    http://www.nasm.us/docs.php aunque realmente existe documentacin ms actualizada como en

    su sitio de Sourceforge o Git, por ejemplo. Lo ms recomendable es utilizar la versin estable.

    2. El compilador e intrprete, 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 terminacin rc, por ejemplo abriremos la carpeta

    2.11.05 (fijate que no dice 2.11.05rc) estando dentro bajaremos el compilador e intrprete 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

    distincin 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 terminacin .tar.gz (nasm-

    2.11.05.tar.gz, por ejemplo) ya vern porque ms adelantito.

    3. El enlazador para Windows OS (para Linux no es necesario):

    UNIVERSIDAD JUREZ AUTNOMA DE TABASCO DIVISIN ACADMICA DE INFORMTICA Y SISTEMAS

  • Pgina 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 lnea de comandos.

    Ahoa la siguiete uesti es Qu hago o todo esto paa epeza a ola pogaado e Lenguaje ensamblador? Pues lo siguiente:

    QU HAGO CON TODOS LOS RECURSOS QUE NECESITO?

    Aqu hago distincin 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 continuacin.

    2. Una vez que est instalado recurrimos al acceso directo que haba 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

    opcin Abrir la ubicacin del archivo vamos a ubicarnos donde se encuentran todos los recursos de

    instalacin. Esta carpeta la mantendremos abierta nos ser til unos pasos ms adelante.

  • Pgina 4 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    3. Se supone que todava 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 extrados en una carpeta dentro de la carpeta ..\AppData\Local\nasm deben estar en la

    misma jerarqua.

    4. Lo siguiente es copiar la ruta de instalacin y agregarla a PATH en las variables de entorno de

    Windows. Ustedes ya saben cmo, nos quedara ms 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--)

  • Pgina 5 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    Despus de esto nos mandar fuera de ejecucin de alink. Lo que sigue aqu mismo es

    verificar que se conserva la armona con el depurador nativo de Windows para lo que

    escribiremos debug y despus 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 adems necesitarn 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 ubicacin 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.

  • Pgina 6 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    En Linux:

    1. Para instalar NASM en Linux hay dos vas una es por va repositorio escribiendo sudo apt-get

    install nasm lo cual nos instalar una versin sumamente antigua y la otra es por medio de la

    compilacin 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 instalacin a /usr/local/bin luego comprobamos que

    efectivamente tenemos instalado nasm como se ilustra en la siguiente imagen.

    Debo mencionar que las ubicaciones simblicas indican que en nuestro sistema instalo

    correctamente a nasm.

  • Pgina 7 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    1.3. Tenemos la opcin 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 ubicacin /usr/local/src/ pues

    ya no los necesitamos.

    Y listo ya tenemos todo listo para empezar con NASM desde Linux. Al parecer fue ms rollo para

    Windows, disculpen...

    A PROGRAMAR!

    Para saber cmo trabajar con nasm consulte la documentacin 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 tradicin y para explicar la manera de trabajar que

    consiste en editar un archivo .asm y compilarlo con nasm. Veamos cmo 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 cdigo.

  • Pgina 8 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    Para compilarlo escribimos nasm holawindows.asm -o holawindows.[com, exe] en muestro caso

    exe con la instruccin de salida de nasm (-o). Despus damos Enter, revisamos que efectivamente

    ha sido creado y lo mandamos a ejecutar escribiendo el nombre del archivo sin extensin para

    comprobar. Lo mismo pasara si decidiramos generar un ejecutable .com slo que lo ejecutaramos

    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 ejecucin (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 cdigo.

    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 ejecucin y luego el archivo objeto

    binario. Despus damos Enter, revisamos que efectivamente 2 archivos han sido creados y lo

    mandamos a ejecutar escribiendo ./holalinux el nombre del archivo sin extensin para comprobar.

  • Pgina 9 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    CDIGO:

    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 instrccin de interrupcin

    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 ; direccin 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

  • Pgina 10 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    length: equ 13 ; longitud del string

    2. Plantilla bsica

    Antes de empezar quiero hacer parntesis. (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 tamao del documento con las demostraciones para ambos

    sistemas operativos.

    Ok Este pogaa osiste e el esueleto ue tiee siaete u pogaa e esalado haciendo uso de declaraciones, comentarios, funciones y constantes. Editamos nuestro archivo

    esqueleto.asm y guardamos.

    Este cdigo realmente no es funcional y nuestro resultado es que manda como salida mensajes de

    error al momento de la compilacin debido a que algunas instrucciones estn incompletas, pues

    solo han sido colocadas en su respectivo lugar pero no se estn manejando con su sintaxis correcta.

    En este caso es enter en la lnea 12, push en la lnea 13 y pop en la lnea 17.

  • Pgina 11 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    CDIGO:

    esqueleto.asm

    segment .data

    ;

    ; data inicializado

    ;

    segment .bss

    ;

    ; data unitilizado

    ;

    segment .text

    global _func

    _func:

    enter n,0 ; lnea 12

    push ; guardar registros lnea 13

    ;

    ; cuerpo de la funcion

    ;

    pop ; devolver registros lnea 17

    mov eax,0 ; retornar valor

    leave

    ret

    Otra forma de tener nuestra plantilla sera como sigue:

    esqueleto2.asm

    segment .data

    ;

    ; data inicializado

    ;

    segment .bss

    ;

    ; data unitilizado

    ;

    segment .text

  • Pgina 12 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    global _func

    _func:

    push ebp ; si necesitamos que esta instruccin 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 cmo podemos trabajar desde ensamblador con cdigo fuente del

    lenguaje C. Para esto, el ejemplo consiste en encontrar el mximo comn divisor con el modo

    sencillo, aqu editamos el archivo mcd.asm con nuestro respectivo cdigo. Lo guardamos.

    Luego creamos nuestro cdigo en C, en este caso lo nombr codigoprincipal.c en el cual solo se

    reciben y envan valores pues el algoritmo se ejecuta en cdigo ensamblador. Lo guardamos.

  • Pgina 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 lnea marca @set BIN=C:\Program Files\Microsoft Visual Studio 12.0\VC\bin 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 optimizacin x86). Luego anlogamente a la opcin -o de nasm

    utilizamos -f para indicar que mande de salida ejecutable x86, luego utilizamos la opcin --prefix

    ms _ para el argumento dado para todas las variables globales o externos, como en C. Lo cual va

    de la mano con el compilador de optimizacin 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.

  • Pgina 14 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    Por ultimo verificamos que nuestro ejecutable .exe si funcione.

    CDIGO:

    mcd.asm

    segment data

    segment bss

  • Pgina 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

    int mcd(int a,int b);

    int main() {

    int result;

    int a;

    int b;

  • Pgina 16 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    a = 46;

    b = 90;

    printf("%d y %d tienen un mcd de %d\n",a,b,mcd(a,b));

    a = 9863;

    b = 41272;

    printf("%d y %d tiene un mcd de %d\n",a,b,mcd(a,b));

    }

    construir.bat

    erase *.obj

    erase *.exe

    @set INCLUDE=C:\Program Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    @set BIN=C:\Program Files\Microsoft Visual Studio 12.0\VC\bin

    nasm -f win32 mcd.asm --prefix _

    cl codigoprincipal.c mcd.obj

    4. Generando nmeros aleatorios

    Este programa consiste en usar el algoritmo inorder para generar un nmero entero aleatorio entre

    un rango especificado ya sea entre nmeros positivos y negativos.

    Suponemos que con los ejemplos anteriores ya tenemos claro cul es nuestro patrn de produccin

    a cdigo final, por lo que no entraremos en tanto detalle redundando en cosas que debemos hacer.

    Ok editaos uesto digo e C ue llaaeos codigo_random.c, en ensamblador enteros_random.asm y nuestro script de builder construir_random.bat y vemos nuestro resultado.

  • Pgina 17 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    CDIGO:

    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 ms grande

    add ebx,1 ; sumar uno

    sub ebx,[ebp+8] ; subtraccin 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

  • Pgina 18 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    codigo_random.c

    #include

    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: %d\n",a,b,enterorandom(a,b));

    a = 5500;

    b = 100;

    printf("Entero aleatorio entre %d y %d: %d\n",a,b,enterorandom(a,b));

    a = -20;

    b = 20;

    printf("Entero aleatorio entre %d y %d: %d\n",a,b,enterorandom(a,b));

    }

    construir_random.bat

    erase *.obj

    erase *.exe

    @set INCLUDE=C:\Program Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    nasm -f win32 enteros_random.asm --prefix _

    cl codigo_random.c enteros_random.obj

  • Pgina 19 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    5. Encontrando nmeros 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 nmeros primos entre una rango que debe ser

    especificado al inicio de ejecucin.

    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.

    CDIGO:

    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:

  • Pgina 20 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    enter 0,0

    pushad

    pushfd

    ; pedir lmites 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 divisin

    mov ebx,[factor]

    cdq

    idiv ebx

    cmp edx,0

    je siguiente

    add dword [factor],1 ; empujar factor y ciclar

    jmp factortest

  • Pgina 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();

    }

  • Pgina 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

  • Pgina 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 ; direccin para almacenar cadena

    mov byte [ebx],0

    mov ecx,str_len ; longitud mxima de la cadena

    .in_string_loop:

    call getchar

  • Pgina 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

  • Pgina 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

  • Pgina 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

  • Pgina 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

  • Pgina 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:

  • Pgina 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 direccin

    mov eax,[flags]

    test eax,DF_BIT

  • Pgina 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 lnea

    push dword newline_string

    call out_string

    pop eax

    popfd

    popad

    leave

    ret

    ; ----------------------------

    global out_hex_registers

    out_hex_registers:

    enter 0,0

  • Pgina 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

  • Pgina 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 Files\Microsoft Visual Studio 12.0\VC\include

  • Pgina 33 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    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

    Adems, 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. Manipulacin de bits: desplazando y alternando

    Este programa es una coleccin de mtodos 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 coleccin de mtodos, 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 mtodo por separado. Reutilizamos el archivo con el

    cdigo de salida.asm para no tener problemas con los caracteres de salida y mostrar.asm de donde

    invocamos la funcin 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 cdigo creados

    para la manipulacin 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 mtodo.

  • Pgina 34 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    CDIGO:

    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

  • Pgina 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:

  • Pgina 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

  • Pgina 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

  • Pgina 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

    void aritmetica_izquierda(void);

    int main()

    {

    aritmetica_izquierda();

    }

    aritmetica_derecha.c

    #include

    void aritmetica_derecha(void);

    int main()

    {

    aritmetica_derecha();

    }

    logica_izquierda.c

    #include

  • Pgina 39 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    void logica_izquierda(void);

    int main()

    {

    logica_izquierda();

    }

    logica_derecha.c

    #include

    void logica_derecha(void);

    int main()

    {

    logica_derecha();

    }

    alternar_izquierda.c

    #include

    void alternar_izquierda(void);

    int main()

    {

    alternar_izquierda();

    }

    alternar_derecha.c

    #include

    void alternar_derecha(void);

    int main()

    {

  • Pgina 40 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    alternar_derecha();

    }

    acarreo_alternar_izquierda.c

    #include

    void acarreo_alternar_izquierda(void);

    int main()

    {

    acarreo_alternar_izquierda();

    }

    acarreo_alternar_derecha.c

    #include

    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

  • Pgina 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

  • Pgina 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

  • Pgina 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 direccin

    mov eax,[flags]

    test eax,DF_BIT

    jz df_not

    push df_string

    call out_string

    pop eax

    df_not:

  • Pgina 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 lnea

    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

  • Pgina 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

  • Pgina 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'

  • Pgina 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 Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    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 aplicaramos la misma lgica, y la sintaxis del ejemplo anterior.

  • Pgina 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 especficas para cada tipo de operacin, accediendo a las banderas de paridad, zero y

    signo. Teniendo esta idea necesitamos cdigo de prueba para mostrar los bits originales sobre los

    cuales se harn las operaciones. Entonces hacemos lo siguiente.

    Como en el ejemplo anterior, creamos en este caso nuestra coleccin de las funciones que realizan

    cada tipo de operacin booleana y anexamente nuestro cdigo de prueba que genera los bits

    originales que se utilizan como prueba con las banderas. Nuestros recursos son modos_boolean.asm

    que es nuestra coleccin de funciones, los archivos de cdigo C que son: and.c, or.c, xor.c, not.c y

    test.c que implementan cada funcin, reutilizamos mostrar.asm, salida.asm y nuestro constructor

    para nuestros recursos de cdigo como en el ejemplo anterior. Ahora vemos nuestro resultado.

    CDIGO:

    modos_boolean.asm

    segment .data

    segment .bss

    segment .text

    Prueba original

    con las banderas.

    Implementando

    las funciones.

  • Pgina 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

  • Pgina 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

  • Pgina 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

    void testbits(void);

    int main(){

    testbits();

    }

  • Pgina 52 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    and.c

    #include

    void andbits(void);

    int main() {

    andbits();

    }

    or.c

    #include

    void orbits(void);

    int main(){

    orbits();

    }

    xor.c

    #include

    void xorbits(void);

    int main(){

    xorbits();

    }

    not.c

    #include

    void notbits(void);

    int main(){

    notbits();

    }

  • Pgina 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 Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    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

  • Pgina 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. Eleccin sin rbol: escoger nmero ms grande

    En este programa hacemos uso del algoritmo de bsqueda de una pasada para encontrar el nmero

    ms grandes entre dos valores ingresados al inicio de ejecucin (sin importar orden y tamao de

    nmero). En este ejemplo podemos revisar cmo 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 funcin, 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 cdigo. Nuestro resultado es el siguiente.

    CDIGO:

    escoger.asm

    segment .data

  • Pgina 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

  • Pgina 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

    void escoger(void);

    int main() {

    escoger();

    }

    entrada.asm

  • Pgina 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 Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    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 ms de cdigo 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

    mtodo bubble sort, aunque en la salida no se pueda apreciar en primera instancia.

    Versin 1: Aqu los recursos de cdigo son codigo_por_cuatro.c, por_cuatro.asm y

    construir_arreglos.bat con lo cual obtendremos el siguiente resultado.

  • Pgina 58 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    Versin 2:

    Aqu los recursos de cdigo son codigo_ordenar.c, ordenar.asm y construir_arreglos.bat con lo cual

    obtendremos el siguiente resultado. Aqu los valores de cada posicin han sido ordenados por el

    mtodo bubble sort (ordenamiento burbuja).

    CDIGO:

    codigo_por_cuatro.c

    #include

    void por_cuatro(int tamanio,int arr[]);

    int main()

    {

    int i;

    int tamanio=10;

    int array[10];

    for(i=0; i

  • Pgina 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] ; tamao del arreglo

    top:

    mov eax,[ebx]

    shl eax,2

    mov [ebx],eax

    add ebx,4

    loop top

    leave

    ret

    codigo_ordenar.c

    #include

    void a_ordenar(int tamanio,int arr[]);

    int array[] = { 5,32,87,4,92,11,34,3,84,60,17 };

    int main()

    {

  • Pgina 60 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    int i;

    int tamanio = sizeof(array) / sizeof(int);

    for(i=0; i

  • Pgina 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 Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    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 ecuacin cuadrtica

    En este programa tratamos con nmeros de punto flotante para que de acuerdo a este tipo de valor

    llevemos a cabo instrucciones condicionales. El ejemplo elegido es el clculo de la ecuacin

    cuadrtica donde una solucin puede ser positiva y otra negativa, enteras o de punto flotante,

    infinito negativo e infinito positivo, etc. Digamos que, tratamos con una cuestin prctica donde se

    requiere exactitud en los clculos.

    Para este caso los recursos de cdigo creados son codigo_cuadratica.c, cuadratica.asm y

    construir_cuadratica.bat, y el comportamiento que obtenemos es el siguiente.

  • Pgina 62 de 66

    Materia: Lenguaje Ensamblador Clave: F1265

    CDIGO:

    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

  • Pgina 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)

  • Pgina 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

    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: ");

  • Pgina 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 %g\n",solucion1,solucion2);

    }

    } while(1);

    }

    construir_cuadratica.bat

    erase *.obj

    erase *.exe

    @set INCLUDE=C:\Program Files\Microsoft Visual Studio 12.0\VC\include

    @set LIB=C:\Program Files\Microsoft Visual Studio 12.0\VC\lib;C:\Program Files\Microsoft

    SDKs\Windows\v7.1A\Lib

    nasm -f win32 cuadratica.asm --prefix _

    cl codigo_cuadratica.c cuadratica.obj

    FUENTES ANEXAS:

    Las siguientes fuentes de informacin hacen referencia a documentos (e-books) publicados que son

    de utilidad para estudiar la programacin 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 programacin 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.

  • Pgina 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

    Lenguaje Ensamblador: Guia prcticaQU NECESITO?QU HAGO CON TODOS LOS RECURSOS QUE NECESITO?A PROGRAMAR!1. Hola mundo2. Plantilla bsica3. Ensamblando y enlazando con C: ejemplo mcd4. Generando nmeros aleatorios5. Encontrando nmeros primos6. Manipulacin de bits: desplazando y alternando7. Operaciones booleanas: and, or, xor, not8. Eleccin sin rbol: escoger nmero ms grande9. Arreglos: definiendo y manejando direcciones10. Punto flotante: ejemplo ecuacin cuadrtica

    FUENTES ANEXAS: