Páginas

miércoles, 29 de febrero de 2012

martes, 28 de febrero de 2012

[CÓMPUTO INTEGRADO] Arquitectura MIPS y simulador SPIM

Aquí van algunas cosas sobre la arquitectura MIPS:

Primero que nada, los diseños del MIPS son utilizados en la línea de productos informáticos de SGI; en muchos sistemas embebidos; en dispositivos para Windows CE; routers Cisco; y videoconsolas como la Nintendo 64 o las Sony PlayStation, PlayStation 2 y PlayStation Portable.

Existe un simulador MIPS R2000/R3000 totalmente libre llamado SPIM compatible con varios sistemas operativos ideado para el aprendizaje de la programación en ensamblador MIPS y de los conceptos generales del ensamblador.

Un emulador MIPS más completo pertenece al proyecto GXemul, el cual no sólo emula las diferentes versiones de los microprocesadores MIPS III y superiores, sino también sistemas enteros que utilicen esos procesadores.

Por ejemplo, GXemul puede emular tanto una DECstation con un procesador MIPS R4400 como un SGI O2 con CPU MIPS R10000, entre otros, así como también diferentes framebuffers y controladoras SCSI.

El software QEMU es capaz de emular también, entre muchas otras, la arquitectura MIPS y MIPSel, así como ejecutar GNU/Linux en la máquina emulada.

Hablando de MIPS, este posee ciertas características:
  • Los procesadores MIPS generalmente fueron de 32 bits, a excepción de los más actuales.
  • Su arquitectura es RISC (Reduced Instruction Set Computer)
  • Tiene 32 registros de 32 bits.
Juegos de registros:
  • $zero tiene cableado el valor numérico cero.
  • Los registros $a0, $a1, $a2 y $a3 se utilizan para pasar parámetros a subrutinas.
  • $v0 y $v1 se utilizan para devolver valores de subrutinas.
  • El registro $ra contiene la dirección de retorno y se utiliza para volver después de una llamada a subrutina.
  • Los registros $s0, $s1, $s2, $s3, $s4, $s5, $s6 y $s7 son registros salvados. 
  • Los registros $t0, $t1, $t2, $t3, $t4, $t5, $t6, $t7, $t8 y $t9 son registros temporales.
  • El registro $gp contiene el puntero global.
  • El registro $sp contiene el puntero de pila.
  • El registro $fp contiene el puntero de marco de pila.
  • El registro $at está reservado para el uso por el ensamblador y no debe ser usado por los programadores.
  • Los registros $k0 y $k1 están reservados para su uso por el núcleo del sistema operativo
Existen 3 registros especiales de 32 bits:
  • pc es el registro contador de programa que almacena la dirección de la siguiente instrucción a ejecutar.
  • hi y lo almacenan el resultado de operaciones de multiplicación o división que generan resultados de 64 bits:
    • hi almacena la parte alta del registro
    • lo almacena la parte baja del registro
Directivas MIPS:

.data Los elementos siguientes se almacenan en segmento de datos.
.text Los elementos siguientes se almacenan en segmento de código (texto).
.ascii "tira de caracteres" Almacena cadena de caracteres NO terminada en caractér nulo.
.asciiz "tira de caracteres" Almacena cadena de caracteres terminada en caracter nulo.
.byte 1, 2, 3 Almacena bytes en memoria, consecutivamente.
.half 300, 301, 302 Almacena medias palabras en memoria, consecutivamente.
.word 80000, 80001 Almacena palabras en memoria, consecutivamente.
. float 1.23, 2.23 Almacena valores flotantes en memoria, consecutivamente.
.double 3.0e21 Almacena dobles en memoria, consecutivamente.
.space 10 Reserva un espacio de 10 bytes e el segmento actual.
.extern etiqueta n Declara que etiqueta es global de tamaño n
.globl etiqueta Declara etiqueta como global
.align n Alínea el siguiente dato en un límite de 2^n

Tipos de instrucciones: 
  • Aritméticas y lógicas
    • addRd,R1,R2 #add,addi,addu,addiu – Comparación
    • seq Rd, R1, R2 # seq, sge, sgt, sle, slt, slti, ...
  • Carga y almacenamiento
    • la Rd label # la, lb, lbu, lh, lw (Carga)
    • swRolabel #sb,sh,sw(Almacenamiento)
  • Salto condicional e incondicional
    • beqR1,R2,label #beqz,bge,bgt,ble,...
  • Manejo excepciones / interrupciones
    • rfe,nop,breakn,syscall.
Codigos de llamadas a sistema:



    jueves, 23 de febrero de 2012

    [CÓMPUTO INTEGRADO] Programa MIPS

    En esta parte mostraré y explicare el código de un programa en ensamblador de MIPS explicando cada sección del código:

    Primero que nada el código:

    .data
    prompt:     .asciiz "Enter in an integer: "
    str1:  .asciiz "the answer is: "
    newline:  .asciiz "\n"
    bye:  .asciiz "Goodbye!\n"
     .globl main
    
     .text
    main:
    
     # Inicializando
     li $s0, 10
    
     # Imprime la linea para captura de datos
     li $v0, 4       # Carga $v0 para imprimir un string 
     la $a0, prompt  # Carga en $a0 la dirección de prompt
     syscall              # Se hace la llamada al sistema
    
     # Lee el valor
     li $v0, 5       # Carga $v0 para leer un entero
     syscall              # Se hace la llamada al sistema
     move  $s0, $v0     # Mueve el valor de $v0 a $s0
    
    
    loop:
     # Imprime str1
     li $v0, 4       # Carga $v0 para imprimir un string
     la $a0, str1    # Carga en $a0 la dirección de str1
     syscall           # Se hace la llamada al sistema
    
     # Imprime el valor del loop
     li $v0, 1  # Carga $v0 para imprimir un entero
     move $a0, $s0 # Mueve $s0 a $a0
     syscall   # Se hace llamada al sistema
    
     # Imprime el nuevo valor
     li $v0, 4  # Carga $v0 para imprimir un string
     la $a0, newline  # Carga en $a0 la direción de newline
     syscall   # Se hace llamada al sistema
    
     # Decrementa la variable
     sub $s0, $s0, 1     # Iguala $s0 a $s0 -1
     bgez $s0, loop    # Si $s0 >= 0 regresa a loop, si no, continua.
    
     # Imprime mensaje de adios
     li $v0, 4  # Carga $v0 para imprimir un string
     la $a0, bye # Carga en $a0 la dirección de bye
     jr  $ra  # Se guardan registros en $ra y sale del programa
    
    
    
    

    [CÓMPUTO INTEGRADO] Tarea intro

    Mi programa trata de hacer una simple matriz de 5 por 5.

    Primero que nada, mi intención era mostrar el código generado por Mac OS X, sin embargo es un poco complicado ya que muestra demaciadas lineas a comparación de las que genera Ubuntu 10.10, mostrare a modo de ejemplo ambos códigos generados y pasare a explicar el código modificado de Ubuntu.

    Éste es el código en C. Los números se generan de manera aleatoria.

    #include (stdio.h)
    
    int main(void){
      srand(time(0));
      int i = 0, j = 0;
      int matriz[5][5];
      for (i = 0; i <= 5; i++){
        for (j = 0; j<=5; j++){
          matriz[i][j]=(rand () %9)+1;
        }
      }
      for (i = 0; i <= 5; i++){
        for (j = 0; j<=5; j++){
          printf("%d",matriz[i][j]);
        }
        printf("\n");
      }
     
      return 0;
    }
    
    Éste es el código ensamblador autogenerado del archivo anterior con el comando "gcc -S archivo.c" de Ubuntu.
    .file "matriz.c"                      # Nombre del archivo
    .section .rodata                 #
    
    .LC0:                                   # Etiqueta para el string
    .string "%d "                           # El string
    
    .text                                   # Inicio
    .globl main                             # Indica que main es global
    .type main, @function                 # Indica que main es una función
    
    main:                                   # Inicio de main
     pushl %ebp                            # Se coloca ebp al inicio
     movl %esp, %ebp                      # Se mueve esp a ebp
     andl $-16, %esp                      # Operación lógica entre esp y -16
     pushl %esi                            # Registro esi
     pushl %ebx                            # Registor ebx
     subl $136, %esp                      # Se reserva espacio en esp
     movl $0, (%esp)                      # Se asigna la dirección 0 a esp
     call time                            # Se llama a time de la librería estandar
     movl %eax, (%esp)                    # Se mueve eax a esp
     call srand                           # Se llama a srand de la librería estandar
     movl $0, 124(%esp)                   # Se asigna la dirección 0 a la posición 124 de esp
     movl $0, 120(%esp)                   # Se asigna la dirección 0 a la posición 120 de esp
     movl $0, 124(%esp)                   # Se asigna la dirección 0 a la posición 124 de esp
     jmp .L2                             # Se salta a la sección L2
    
    .L5:                                    # Sección L5
     movl $0, 120(%esp)                   # Se mueve la dirección 0 a la posición 120 dde esp
     jmp .L3                             # Salta a L3
    
    .L4:                                    # Sección L4
    movl 124(%esp), %ebx                 # Se mueve el valor de la posición 124 de esp a ebx
    movl 120(%esp), %esi                 # Se mueve el valor de la posición 120 de esp a esi
    call rand                            # Se llama a rand de la librería estandar
    movl %eax, %ecx                      # Se mueve eax a ecx
    movl $954437177, %edx                # Se asigna la dirección 954437177 a edx 
    movl %ecx, %eax                      # Se mueve ecx a eax
    imull %edx                            # Se multiplica edx por 1
    sarl %edx                            # Se desplaza 1 posición a la derecha en edx
    movl %ecx, %eax                      # Se mueve ecx a eax
    sarl $31, %eax                       # Se desplaza 31 posiciones a la derecha en eax
    subl %eax, %edx                      # Se resta eax a edx
    movl %edx, %eax                      # se mueve edx a eax
    sall $3, %eax                        # Se desplaza 3 posiciones a la izquierda en eax
    addl %edx, %eax                      # Se agrega edx a eax
    movl %ecx, %edx                      # Se mueve ecx a edx
    subl %eax, %edx                      # Se resta eax a ecx
    addl $1, %edx                        # Se agrega 1 a edx
    movl %ebx, %eax                      # Se mueve ebx a eax
    sall $2, %eax                        # Se desplaza dos posiciones a la izquierda en eax
    addl %ebx, %eax                      # Se agrega ebx a eax
    addl %esi, %eax                      # Se agrega esi a eax
    movl %edx, 20(%esp,%eax,4)           #########
    addl $1, 120(%esp)                   # Se agrega 1 al valor de la posición 120 de esp
    
    .L3:                                    # Sección L3
    cmpl $5, 120(%esp)                   # Comparación entre 5 y el valor de la posición 120 de esp
    jle .L4                             # Salta a L4 si la comparación anterior es menor o igual al valor de esp
    addl $1, 124(%esp)                   # Se agrega 1 al valor de la posición 124 de esp
    
    .L2:                                    # Sección L2
    cmpl $5, 124(%esp)                   # Comparación entre 5 y el valor de la posición 124 de esp
    jle .L5                             # Salta a L5 si la comparación anterior es menor o igual al valor de esp
    movl $0, 124(%esp)                   # Se asigna la dirección 0 a la posición 124 de esp
    jmp .L6                             # Se salta a la sección L6
    
    .L9:                                    # Sección L9
    movl $0, 120(%esp)                   # Se asigna la dirección 0 a la posición 120 de esp
    jmp .L7                             # Salta a la sección L7
    
    .L8                                     # Sección L8
    movl 124(%esp), %edx                 # Se asigna el valor de la posición 124 de esp a edx
    movl 120(%esp), %ecx                 # Se asigna el valor de la posición 120 de esp a ecx
    movl %edx, %eax                      # Se mueve edx a ecx
    sall $2, %eax                        # Se desplaza dos posiciones a la izquierda en eax
    addl %edx, %eax                      # Se agrega el valor de edx a eax
    addl %ecx, %eax                      # Se agrega el valor de ecx a eax
    movl 20(%esp,%eax,4), %edx           #########
    movl $.LC0, %eax                     # Se asigna el string LC0 a eax
    movl %edx, 4(%esp)                   # Se mueve edx a la posición 4 de esp
    movl %eax, (%esp)                    # Se mueve eax a el principio de esp
    call printf                          # Se llama a printf de la librería estandar
    addl $1, 120(%esp)                   # Se agrega 1 a la posición 120 de esp
    
    .L7:                                    # Sección L7
    cmpl $5, 120(%esp)                   # Comparación entre 5 y el valor de la posición 120de esp
    jle .L8                             # Salta a L8 si la comparación anterior es menor o igual al valor de esp
    movl $10, (%esp)                     # Se asigna 10 al inicio de esp
    call putchar                         # Se llama a putchar de la librería estandar
    addl $1, 124(%esp)                   # Se agrega 1 a la posición 124 de esp
    
    .L6:                                    # Sección L6
    cmpl $5, 124(%esp)                   # Comparación entre 5 y el valor de la posición 124 de esp
    jle .L9                             # Salta a L9 si la comparación anterior es menor o igual al valor de esp
    movl $0, %eax                        # Se asigna el valor 0 a eax
    addl $136, %esp                      # Se agrega 136 a esp
    popl %ebx                            # Sale ebx
    popl %esi                            # Sale esi
    movl %ebp, %esp                      # Se mueve ebp a esp
    popl %ebp                            # Sale ebp
    ret                                     # Return, fin del programa
    
    .size main, .-main
    .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section .note.GNU-stack,"",@progbits
    
    
    Este es el código generado por Mac OS X
     .section __TEXT,__text,regular,pure_instructions
     .globl _main
     .align 4, 0x90
    _main:
    Leh_func_begin1:
     pushq %rbp
    Ltmp0:
     movq %rsp, %rbp
    Ltmp1:
     subq $128, %rsp
    Ltmp2:
     xorl %eax, %eax
     xorb %cl, %cl
     movl %eax, %edi
     movb %cl, %al
     callq _time
     movl %eax, %ecx
     xorb %dl, %dl
     movl %ecx, %edi
     movb %dl, %al
     callq _srand
     movl $0, -12(%rbp)
     movl $0, -16(%rbp)
     movl $0, -12(%rbp)
     jmp LBB1_5
    LBB1_1:
     movl $0, -16(%rbp)
     jmp LBB1_3
    LBB1_2:
     movl -12(%rbp), %eax
     movl -16(%rbp), %ecx
     xorb %dl, %dl
     movl %eax, -120(%rbp)
     movb %dl, %al
     movl %ecx, -124(%rbp)
     callq _rand
     movl %eax, %ecx
     movl $954437177, %esi
     movl %ecx, %eax
     imull %esi
     movl %edx, %eax
     movl %eax, %esi
     shrl $31, %esi
     sarl %eax
     leal (%rax,%rsi), %eax
     movl %eax, %esi
     leal (%rax,%rsi,8), %eax
     negl %eax
     leal 1(%rcx,%rax), %eax
     movl -120(%rbp), %ecx
     movslq %ecx, %rcx
     movq %rcx, %rsi
     leaq (%rcx,%rsi,4), %rcx
     leaq -116(%rbp,%rcx,4), %rcx
     movl -124(%rbp), %esi
     movslq %esi, %rsi
     movl %eax, (%rcx,%rsi,4)
     movl -16(%rbp), %eax
     leal 1(%rax), %eax
     movl %eax, -16(%rbp)
    LBB1_3:
     movl -16(%rbp), %eax
     cmpl $5, %eax
     jle LBB1_2
     movl -12(%rbp), %eax
     addl $1, %eax
     movl %eax, -12(%rbp)
    LBB1_5:
     movl -12(%rbp), %eax
     cmpl $5, %eax
     jle LBB1_1
     movl $0, -12(%rbp)
     jmp LBB1_11
    LBB1_7:
     movl $0, -16(%rbp)
     jmp LBB1_9
    LBB1_8:
     movl -12(%rbp), %eax
     movl -16(%rbp), %ecx
     movslq %eax, %rax
     leaq -116(%rbp), %rdx
     movabsq $20, %rsi
     imulq %rsi, %rax
     addq %rax, %rdx
     movslq %ecx, %rax
     movl (%rdx,%rax,4), %eax
     xorb %cl, %cl
     leaq L_.str(%rip), %rdx
     movq %rdx, %rdi
     movl %eax, %esi
     movb %cl, %al
     callq _printf
     movl -16(%rbp), %eax
     addl $1, %eax
     movl %eax, -16(%rbp)
    LBB1_9:
     movl -16(%rbp), %eax
     cmpl $5, %eax
     jle LBB1_8
     movl $10, %eax
     movl %eax, %edi
     callq _putchar
     movl -12(%rbp), %eax
     addl $1, %eax
     movl %eax, -12(%rbp)
    LBB1_11:
     movl -12(%rbp), %eax
     cmpl $5, %eax
     jle LBB1_7
     movl $0, -8(%rbp)
     movl -8(%rbp), %eax
     movl %eax, -4(%rbp)
     movl -4(%rbp), %eax
     addq $128, %rsp
     popq %rbp
     ret
    Leh_func_end1:
    
     .section __TEXT,__cstring,cstring_literals
    L_.str:
     .asciz  "%d "
    
     .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
    EH_frame0:
    Lsection_eh_frame:
    Leh_frame_common:
    Lset0 = Leh_frame_common_end-Leh_frame_common_begin
     .long Lset0
    Leh_frame_common_begin:
     .long 0
     .byte 1
     .asciz  "zR"
     .byte 1
     .byte 120
     .byte 16
     .byte 1
     .byte 16
     .byte 12
     .byte 7
     .byte 8
     .byte 144
     .byte 1
     .align 3
    Leh_frame_common_end:
     .globl _main.eh
    _main.eh:
    Lset1 = Leh_frame_end1-Leh_frame_begin1
     .long Lset1
    Leh_frame_begin1:
    Lset2 = Leh_frame_begin1-Leh_frame_common
     .long Lset2
    Ltmp3:
     .quad Leh_func_begin1-Ltmp3
    Lset3 = Leh_func_end1-Leh_func_begin1
     .quad Lset3
     .byte 0
     .byte 4
    Lset4 = Ltmp0-Leh_func_begin1
     .long Lset4
     .byte 14
     .byte 16
     .byte 134
     .byte 2
     .byte 4
    Lset5 = Ltmp1-Ltmp0
     .long Lset5
     .byte 13
     .byte 6
     .align 3
    Leh_frame_end1:
    
    
    .subsections_via_symbols
    
    Ambos códigos tienen una sintaxis parecida, ya que en ambos utilicé una versión de gcc para el sistema. Pero en Ubuntu me lanza menos lineas de código y me es más comprensible, mientras que en OS X lanza demasiadas lineas de debug mezcladas con el código principal.

    Ahora, analizaremos cada sección del programa, gcc me dividió el código en 9 secciones. La sección del main define principalmente los registros que se utilizaran durante la ejecución, aparte ejecuta funciones estandar llamadas en el código.

    main:
    main:
     pushl %ebp      
     movl %esp, %ebp 
     andl $-16, %esp
     pushl %esi      
     pushl %ebx    
     subl $136, %esp 
     movl $0, (%esp) 
     call time       
     movl %eax, (%esp)
     call srand       
     movl $0, 124(%esp)
     movl $0, 120(%esp)
     movl $0, 124(%esp)
     jmp .L2          
    Esta parte del código se encarga de colocar las variables en el programa, llama a srand y a time para generar un número aleatorio.

    L2:
    .L2:                                    
     cmpl $5, 124(%esp)                   
     jle .L5                             
     movl $0, 124(%esp)                   
     jmp .L6                             
    
    
    L2 se encarga de hacer la comparación entre el valor de "esp" y el número 5. ¿Por qué esto? Porque la matriz sera de 5 x 5, se puede decir que L2 es la parte del código donde se comprueba una dimención de la matriz, y se guarda su dirección para saber donde guardar los números generados.

    L5:
    .L5:
     movl $0, 120(%esp)
     jmp .L3
                            
    
    En L5 solo se guarda un 0 en la posición 120 de "esp" y se salta a L3.

    L3:
    .L3:
     cmpl $5, 120(%esp)
     jle .L4          
     addl $1, 124(%esp) 
    
    
    En esta parte se vuelve a hacer una comparación, esta vez para asignar la segunda dimención de la matriz y se guardara en la posición 120 de "esp". Salta a la sección L4. En esta parte se vuelve a hacer una comparación, esta vez para asignar la segunda dimención de la matriz y se guardara en la posición 120 de "esp". Salta a la sección L4.

    Como en los casos anteriores ocurren comparaciones, no se saldra de esas secciones hasta que las coparaciones acierten el "jle" que es un if que comprueba que el valor dado sea menor o igual al del parametro dado, por lo que esta parte seria como el "for" que todos conocen.

    L4:
    .L4:                       
    movl 124(%esp), %ebx    
    movl 120(%esp), %esi    
    call rand               
    movl %eax, %ecx         
    movl $954437177, %edx    
    movl %ecx, %eax         
    imull %edx               
    sarl %edx               
    movl %ecx, %eax         
    sarl $31, %eax          
    subl %eax, %edx         
    movl %edx, %eax         
    sall $3, %eax           
    addl %edx, %eax           
    movl %ecx, %edx           
    subl %eax, %edx           
    addl $1, %edx             
    movl %ebx, %eax           
    sall $2, %eax             
    addl %ebx, %eax           
    addl %esi, %eax           
    movl %edx, 20(%esp,%eax,4)
    addl $1, 120(%esp)        
    
    
    Esta parte es donde se asignan los números aleatorios, en "ebx" y en "esi" se trataran los números generados en forma aleatoria, estos se suman en "eax", en "edx" se guarda un número "954437177" que se guarda como un entero y se resta a "eax" para poner el límite de 0 a 9 a la hora de generar los números, "eax" se suma a "ebx" de nuevo y finalmente pasa a la posición 120 de "esp" y se guarda el número generado.

    L4 regresa a L3, L3 a L5 y L5 a L2. El número generado se guarda en la posición 124 de "esp", ahora salta a L6.

    L6:
    .L6:                    
     cmpl $5, 124(%esp)   
     jle .L9             
     movl $0, %eax        
     addl $136, %esp      
     popl %ebx            
     popl %esi            
     movl %ebp, %esp      
     popl %ebp            
     ret                     
    
    
    En esta sección se vuelve a comprobar la dimención de la matriz, y se salta a L9, los "popl" sacan los registros para finalizar con el "ret".

    L9:
    .L9:
     movl $0, 120(%esp)   
     jmp .L7             
    

    L9 al igual que L5, solo guarda la dirección en 120 de "esp", pero esta ocación en lugar de guardar el número, se va a imprimir en pantalla. Para eso se pasa a L7.

    L7:
    .L7:                     
     cmpl $5, 120(%esp)    
     jle .L8              
     movl $10, (%esp)      
     call putchar          
     addl $1, 124(%esp)    
    

    Esta parte del código hace lo mismo que L3, solo que despues de ejecutar L8 imprime el valor en pantalla. Al haber comparaciones en estos casos tambien, sucede lo mismo que paso anteriormente, por lo que esta parte esria el segundo for del programa, este para recorrer la matriz e imprimir cada valor.

    L8:
    .L8                          
    movl 124(%esp), %edx      
    movl 120(%esp), %ecx      
    movl %edx, %eax           
    sall $2, %eax             
    addl %edx, %eax           
    addl %ecx, %eax           
    movl 20(%esp,%eax,4), %edx
    movl $.LC0, %eax          
    movl %edx, 4(%esp)        
    movl %eax, (%esp)         
    call printf               
    addl $1, 120(%esp)        
    
    
    Esta es la parte final del programa, donde se imprime número por número, imprime los valores almacenados en "esp" que están almacenados en las posiciones 120 y 124, todo se agrega a "eax" y se le hace apuntar a LC0 para que imprima un "%d" que sera reemplazado por el valor guardado, justo como sucede en lenguaje C. Se llama a printf.

    L8 regresa a L7, L7 a L9 y L9 a L6 donde salen los registros y finaliza el programa.

    Los resultados son los siguientes:


    Como vemos hay un error en el código que hace a que genere un número más grande de lo esperado, mejoremos el código un poco.

    Código Mejorado Código Antiguo
    .LC0:
     .string "%d"
     .text
    .globl main
     .type main, @function
    main:
     pushl %ebp
     movl %esp, %ebp
     andl $-16, %esp
     pushl %esi
     pushl %ebx
     subl $136, %esp
     movl $0, (%esp)
     call time
     movl %eax, (%esp)
     call srand
     movl $0, 124(%esp)
     movl $0, 120(%esp)
     jmp .L2
    .L5:
     movl $0, 120(%esp)
     jmp .L3
    .L4:
     movl 124(%esp), %ebx
     movl 120(%esp), %esi
     call rand
     movl $954437177, %edx
     imull %edx
     sarl %edx
     movl %ecx, %eax
     sarl $31, %eax
     subl %eax, %edx
     movl %edx, %eax
     sall $3, %eax
     addl %edx, %eax
     movl %ecx, %edx
     subl %eax, %edx
     addl $1, %edx
     movl %ebx, %eax
     sall $2, %eax
     addl %ebx, %eax
     addl %esi, %eax
     movl %edx, 20(%esp,%eax,4)
     addl $1, 120(%esp)
    .L3:
     cmpl $5, 120(%esp)
     jle .L4
     addl $1, 124(%esp)
    .L2:
     cmpl $5, 124(%esp)
     jle .L5
     movl $0, 124(%esp)
     jmp .L6
    .L9:
     movl $0, 120(%esp)
     jmp .L7
    .L8:
            movl 124(%esp), %edx
     movl 120(%esp), %ecx
     sall $2, %edx
     addl %edx, %eax
     addl %ecx, %eax
     movl 20(%esp,%eax,4), %edx
     movl $.LC0, %eax
     movl %edx, 4(%esp)
     movl %eax, (%esp)
     call printf
     addl $1, 120(%esp)
    .L7:
     cmpl $5, 120(%esp)
     jle .L8
     movl $10, (%esp)
     call putchar
     addl $1, 124(%esp)
    .L6:
     cmpl $5, 124(%esp)
     jle .L9
     movl $0, %eax
     addl $136, %esp
     popl %ebx
     popl %esi
     movl %ebp, %esp
     popl %ebp
     ret
    
    
     .file "matriz.c"
     .section .rodata
    .LC0:
     .string "%d"
     .text
    .globl main
     .type main, @function
    main:
     pushl %ebp
     movl %esp, %ebp
     andl $-16, %esp
     pushl %esi
     pushl %ebx
     subl $136, %esp
     movl $0, (%esp)
     call time
     movl %eax, (%esp)
     call srand
     movl $0, 124(%esp)
     movl $0, 120(%esp)
     movl $0, 124(%esp)
     jmp .L2
    .L5:
     movl $0, 120(%esp)
     jmp .L3
    .L4:
     movl 124(%esp), %ebx
     movl 120(%esp), %esi
     call rand
     movl %eax, %ecx
     movl $954437177, %edx
     movl %ecx, %eax
     imull %edx
     sarl %edx
     movl %ecx, %eax
     sarl $31, %eax
     subl %eax, %edx
     movl %edx, %eax
     sall $3, %eax
     addl %edx, %eax
     movl %ecx, %edx
     subl %eax, %edx
     addl $1, %edx
     movl %ebx, %eax
     sall $2, %eax
     addl %ebx, %eax
     addl %esi, %eax
     movl %edx, 20(%esp,%eax,4)
     addl $1, 120(%esp)
    .L3:
     cmpl $5, 120(%esp)
     jle .L4
     addl $1, 124(%esp)
    .L2:
     cmpl $5, 124(%esp)
     jle .L5
     movl $0, 124(%esp)
     jmp .L6
    .L9:
     movl $0, 120(%esp)
     jmp .L7
    .L8:
     movl 124(%esp), %edx
     movl 120(%esp), %ecx
            movl %edx, %eax
     sall $2, %eax
     addl %edx, %eax
     addl %ecx, %eax
     movl 20(%esp,%eax,4), %edx
     movl $.LC0, %eax
     movl %edx, 4(%esp)
     movl %eax, (%esp)
     call printf
     addl $1, 120(%esp)
    .L7:
     cmpl $5, 120(%esp)
     jle .L8
     movl $10, (%esp)
     call putchar
     addl $1, 124(%esp)
    .L6:
     cmpl $5, 124(%esp)
     jle .L9
     movl $0, %eax
     addl $136, %esp
     popl %ebx
     popl %esi
     movl %ebp, %esp
     popl %ebp
     ret
     .size main, .-main
     .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
     .section .note.GNU-stack,"",@progbits
    
    
    Despues de unas mejoras y quitando un poco de código de debug, el resultado nuevo es el siguiente:


    miércoles, 22 de febrero de 2012

    [DISPOSITIVOS MÓVILES] Redes en disp. moviles

    En los dispositivos móviles existe una característica especial que destaca en ellos y se puede decir que es la más importante: la comunicación.

    Se puede decir que la comunicación es esencial ya que muchas de sus aplicaciones se basan en ella para demostrar su propósito.

    Existen distintos tipos de sistemas de comunicación que han evolucionado a lo largo del tiempo, por mencionar algunos ejemplos tenemos:

    Comunicaciones 1G

    Son el conjunto de estándares que emplean tecnologías analógicas:


    • AMPS (Advanced Mobile Phone System) con operación a 800MHz utilizado en gran parte de América, África, Europa del Este y Rusia.
    • ETACS (Extended TototalAccesss Comunication System) utilizado en Europa principalmente con una banda de a 900MHz
    • NMT (Nordic Mobile Telephone) con banda de 900MHz en países escandinavos, su versión de 450MHz se utilizó en España.
    Comunicaciones 2G

    La segunda generación de comunicaciones móviles representan a el conjunto de familias de estándares y sistemas de comunicación móviles digitales de banda estrecha. A diferencia de sus antecesores, estas se destinaron a desarrollo de comunicación a nivel regional:

    • GSM (Global System for Movile comunications) es el estándar europeo de telefonía celular 2G con 900 MHz en sus inicios para despues usar bandas de 1800 a 1900 MHz alcanzando velocidades de hasta 9600 bps. Introduce el uso de la tarjeta SIM (Subsciber Identity Module)
    • GPRS (General Packet Radio Service) introduce funcionalidades adicionales a la red GSM, en sus inicios tuvo velocidades de 57.6 kbps, en su segunda fase alcanza velocidades de 115.2 kbps
    • El término 2.5G se refiere a la transición entre redes GSM y GPRS a los nuevos estándares 3G
    • EDGE (Enhanced Data rates for GSM of Evolution) es la tecnología de telefonía celular puente entre las redes 2G y 3G (2.5G). Alcanza velocidades de transmisión de datos de 384 kbps. 
    Comunicaciones 3G

    Son el conjunto de estándares de comunicación móvil con el objetivo de implementar nuevas redes con capacidad de tansmición mayor de datos, supone la llegada de la banda ancha a las comunicaciones móviles.

    • UMTS( Universal Mobile Telecommunications System) hace uso de la técnica de espectro ensanchado lo que le permite una mayor cantidad de transmisión de datos. Con frecuencias que van desde los 1885 a 2025 MHz y en sus futuros sistemas van desde 2110 a 2200 MHz.
    • HSDPA (High Speed Downlink Packet Access) se introduce en el Release 5 del UMTS le permite tener velocidades desde 1.8 hasta los 14 Mbps pasando por los 3.6 y 7.2 Mbps.
    • El término 3.5G se refiere a las nuevas versiones del estándar UMTS que ofrecen mejoras de capacidad, rendimiento y eficiencia con respecto a la primera versión.
    Comunicaciones 4G


    También llamada B3G o Beyond 3G, surge el concepto desde los inicios de la 3G. Supone velocidades de hasta 100 Mbps.

    Acceso inalámbrico

    • Bluetooth es la tecnología de red de área personal inalámbrica (WPAN) desarrollada por el Bluetooth Special Interest Group. Bluetooth es un estándar abierto (IEEE 802.15) para transmisiones de corta distancia de voz digital y datos, que soporta aplicaciones punto a punto y punto a multipunto y trabaja en la banda sin licencia de 2.4 GHz. La señal alcanza una velocidad de 720 Kbps en un radio de hasta 100 metros y es capaz de atravesar paredes.
    • Wi-Fi (Wireless Fidelity) es el estándar creado por el IEEE para las Redes de Acceso Local Inalámbrico (WLAN). Sus principales aplicaciones, son los hot-spots (hoteles, aeropuertos, estaciones de servicio, centros de convenciones y comerciales, pueblos, etc.), en los que se ofrece acceso a Internet, en muchos casos, de forma gratuita. También es ampliamente utilizado en el entorno empresarial y residencial para la construcción de redes de área local inalámbricas.
    Rendimiento

    El uso de estas tecnologías recae en el rendimiento de los dispositivos móviles. Por ejemplo, tener activo el Bluetooth consume drasticamente la energía en cualquier dispositivo, así como el Wi-Fi, poreso surgen discuciones sobre si es bueno tenerlos activos todo el tiempo. 

    La recomendación es que si es inecesario en el momento, apagar estos dispositivos, amenos que vengan activos de fábrica.

    El uso de las distintas redes tambien afecta la duración de batería. Como ejemplo el HTC Google Nexus One, promete (en stand-by) hasta 290 horas con redes 2G y hasta 250 con redes 3G, por lo que la otra recomendación es que si tu operadora no ofrece un cierto tipo de tecnologías, puedes desactivar la búsqueda de estas, ya que estos dispositivos generalmente vienen configurados para conectarse a cualquera de ellas.

    Aplicaciones

    Hablar de aplicaciones en cuanto a redes supone un tema muy largo por lo que colocaré algunas de las más llamativas. En general, cualquier aplicación que haga uso de internet necesitara de las redes.

    El ejemplo clasico del uso de las redes es el de las redes sociales, en este caso hablamos en general de aplicaciones de comunicación:


    Pero una de las aplicaciones más llamativas fue la de Google Maps, que utiliza redes 3G y el GPS.


    Por ultimo tenemos a Wikitude Drive, un buscador GPS que hace uso de realidad aumentada. Esta conectado a una red 3G permanente que aunque tiene una tarifa, no es muy elevada.

    jueves, 16 de febrero de 2012

    [DISTRIBUIDOS Y PARALELOS] Third week

    This week I was reading more about threads, this time about synchronization:

    I was triyng to use mutex (locks) in some codes using threading.Lock from python.

    Also there is threading.Semaphore() and threading.Condition()

    I updated the page I did last week with this information.

    Link to the page

    This week I'll nominate to Cecilia for her mergesort python program using both secuential and parallel ways.
    I'll also nominate Gabriela because I found her post very useful

    jueves, 9 de febrero de 2012

    [MODELADO Y SIMULACIÓN] Sistemas deterministas

    Un sistema determinista es aquel que si se conoce su comportamiento y que cambios o acciones conllevan a un estado, se sabrá cuales serán sus futuros estados.

    Ésto es que si despues de un determinado tiempo o mediante las acciones del entorno un objeto cambia de estado, este es determinista, siempre y cuando sus tareas se hayan cumplido.

    Desde mi punto de vista cualquier cosa que esté hecha para seguir una serie de reglas es un sistema determinista, así sea un foco o bien un sistema más complejo como un circuito que haga determinada tarea.

    Un ejemplo sería un cruce peatonal con semáforos para peatones.

    Algunos cruces peatonales tienen estos semáforos con un botón para pasar. Éstos están programados para cambiar cada cierto tiempo, o bien, cambian dependiendo de cuantas veces se pulsó el botón de cruce.


    Es determinista porque si dado el tiempo determinado nadie oprime el botón, este cambiara a verde para los peatones y rojo para el tráfico. Además e que si el botón es oprimido un número dado de veces, este cambiara a verde en un tiempo determinado, o bien si el tiempo dado se termina.


    Si bien, el número de personas es una variable aleatoria, el semaforo está listo para cambiar ante un número definido de pulsaciones del botón. Quiere decir que su tarea no se ve afectada por esta variable, su estado cambiara ante el tiempo determinado sin fijarse en que momento llegan las personas ni el orden en que llegaron. Es solo una condicion que le da preferencia a un numero dado de personas o mayor a éste.



    Como se ve en las imágenes anteriores, iniciando con el rojo, se dará un tiempo determinado dependiendo de las veces que se pulsó el botón, o bien este sera el tiempo total por defecto, y cambiara su estado a verde.

    El siguiente pseudocódigo dará una idea de la forma que funcionan:

    estado = verde
    tiempo = 1 minuto
    
    def cronometro():
        while x = true:
            tiempo -= 1 segundo
            if tiempo == 1 minuto:
                x = false
                return false
    
    def semaforo():
        if cronometro == false:
            estado = rojo
        elif boton() == false:
            if tiempo <= 45 segudos:
                estado = rojo
            else:
                tiempo -= 45 segundos
    
    def boton():
        while x = true:
            if se presiona boton:
                contador += 1
            if contador == 10:
                x = false
                return false
    
    while true:
        semaforo()
    
    
    Éste es el diagrama de estados ligeramente distinto al pseudocódigo para verse más simple:


    [DISTRIBUIDOS Y PARALELOS] Second week

    This week I tried to modify the code of mergesort in python to make it work with threads, but I found it a little hard.

    At the first try, the results were:


    One instruction was executed as many times as I had defined threads.

    In this link I explain how to work with threads an two diferent ways of execution of them.

    jueves, 2 de febrero de 2012

    [DISTRIBUIDOS Y PARALELOS] Fisrt week

    In this first week I tried to execute mergesort algorithm in python.

    So I looked for information about the algorithm in some pages and I found this:


    First I tried some implementations where I divided a list in pairs and comparing the elements in each list generated from the original list.

    I failed. Becouse I only got a sublist order, but not the full list.

    So I looked again for more information and then I made this code:


    This code works fine, and I tried to implement threads, but it's a little hard.

    miércoles, 1 de febrero de 2012

    [DISPOSITIVOS MÓVILES] Reporte inicial de proyecto

    Este proyecto tiene como objetivo el crear una aplicación capaz de calcular una solución a cualquier Sudoku reglamentario, al decir reglamentario me refiero a que sea un sudoku que se vea así:

    y no así:

    Pero más que dar soluciones a un juego, implementare una de las tecnologías más sobresalientes en cuanto a los nuevos dispositivos móviles: realidad aumentada.

    Hablando un poco sobre realidad aumentada, es la combinación de elementos reales con elementos virtuales. Esto es, poder visualizar objetos generados por computadora u otros dispositivos en una pantalla que muestra a su vez una visión directa del entorno, colocando los objetos virtuales en una posición fija.

    Existen muchas aplicaciones que hacen uso de la realidad aumentada, que van desde juegos hasta aplicaciones que muestran información sobre el entorno en tiempo real.

    En este video se muestra un ejemplo de lo que quiero hacer, es una aplicación para iPhone para resolver el sudoku:


    De parte de Google hay algo parecido, solo que en lugar de realidad aumentada, solo toman una fotografía del juego y muestra aparte la solución del mismo:


    El problema que enfrente en un principio fue el de encontrar alguna librería que sirviera para realidad aumentada, pero con la ayuda de la búsqueda en Google pude encontrar varias librerías. El siguiente problema seria instalarlas en Eclipse.

    Suponiendo que hemos instalado Eclipse con los plugins necesarios para emular Android solo es necesario bajar la librería y abrirla como un proyecto en Eclipse.

    Agregaremos la librería de esta manera, abrimos proyecto nuevo y seleccionamos Android project y damos next:


    Seleccionamos create project from existing source y en location agregamos la dirección de la librería, esta es la que contiene el archivo androidmanifest.xml

    Aparecerá de esta manera:

    Lo siguiente es crear un proyecto cualquiera, para Android por supuesto y linkear la librería al proyecto, para esto hacemos lo siguiente, clic derecho sobre la librería (carpeta TestData) y seleccionar Propertis.


    Seleccionamos Android y en la parte derecha en Library tildamos Is Library.

    Después hacemos lo mismo para el proyecto, clic derecho, seleccionamos Propertis, seleccionamos Android y esta ves haremos lo siguiente:


    Esta vez agregamos una librería con el botón Add, aparecerá la librería anterior y damos clic en ok.

    Desde ahora sera posible utilizar todas las clases de la librería.

    Podremos agregar cualquier librería, yo encontré algunas:

    Look! Framework de Realidad Aumentada para Android

    DroidAR Augmented Reality Framework

    Ambas contienen ligas a tutoriales y a documentación, aún no decido cual utilizar, incluso podría utilizar alguna otra librería.