PRÁCTICAS DE COMPUTADORES II

SEGUNDA SESIÓN


  1. Operaciones aritméticas

    Una vez tenemos datos en nuestros registros, lo primero que podemos necesitar es realizar operaciones con ellos. Las operaciones aritméticas que nos proporciona el 6809 se centran fundamentalmente en sumas/restas de números enteros y operaciones relacionadas. Veámoslas:

    Las órdenes INC, DEC, CLR y NEG se pueden usar también directamente sobre el contenido de una posición de memoria.

  2. Ejemplo

    Veamos, con un pequeño ejemplo, cómo realizar la suma de dos números de 16 bits almacenados en la memoria. Primero lo haremos con el registro D y, posteriormente, solamente con el registro A, para aprender a usar la instrucción ADC:
    
            .area PROG (ABS)
    
            ; definimos una constante
    fin     .equ 0xFF01
    
            .org 0x100
    sumando1: .word 0x2190
    sumando2: .word 0x7777
    
    suma1:  .word 0
    suma2:  .word 0
    
            .globl programa
    programa:
            ; hagamos, primero, la suma con el registro D
            ldd sumando1
            addd sumando2
            std suma1
    
            ; ahora lo vamos a hacer solamente con el registro A
            lda sumando1+1
            adda sumando2+1
            sta suma2+1
            lda sumando1
            adca sumando2
            sta suma2
    
            ; el programa acaba
            clra
            sta fin
    
            .org 0xFFFE     ; vector de RESET
            .word programa
    
    
    Centrémonos en la parte en que se hace la suma con el registro A. Se trata de hacer la suma por columnas de dígitos (en este caso las columnas son de registros) considerando los posibles acarreos a las columnas posteriores, como se hace tradicionalmente:

    Suma de 16 bits con A
  3. Depuración

    El programa del ejemplo anterior, si lo ensamblamos y ejecutamos, no va a producir ninguna salida, por lo que no sabremos si lo hemos hecho bien o no.

    Haciendo de la necesidad virtud, no sólo para poder comprobar el programa anterior, sino también por si necesitáis depurar cualquier otro programa, os presentamos a continuación las posibilidades de depuración del simulador.

    Si al simulador no le prestamos ayuda, nunca sabrá cuáles son los nombres que hemos puesto a nuestras etiquetas, pues estos nombres ya no aparecen en el ejecutable. Esto no es necesario, pero sí conveniente pues ayuda bastante para encontrar errores. Necesitamos, pues, generar una tabla con los símbolos que hemos definido en nuestro programa y pasársela al simulador.

    Para ello, procedemos del modo siguiente:

    1. Añadimos a la orden de ensamblado la opción -a (de all). Esto hace que a la siguiente fase pasen todos los símbolos que hemos usado. Cuando no la ponemos, solamente pasan los símbolos declarados globales con .global. La línea de ensamblado queda así:
      as6809 -a -o suma.asm
      
    2. Le decimos al enlazador que queremos que nos genere un mapa de símbolos (-m) con formato ancho (-w, del inglés wide), que es el que entiende el simulador:
      aslink -s -m -w suma.rel
      
      Tiene que aparecer un fichero de nombre suma.map parte de cuyo contenido es el siguiente:
      Area                       Addr        Size        Decimal Bytes (Attributes)
      --------------------       ----        ----        ------- ----- ------------
      PROG                       0000        0000 =           0. bytes (ABS,OVR,CSEG)
      
               Value  Global                             Global Defined In Module
               -----  --------------------------------   ------------------------
                0100  sumando1                           
                0102  sumando2                           
                0104  suma1                              
                0106  suma2                              
                0108  programa                           
      

    El simulador es lo suficientemente listo para ver que si hay un fichero con el mismo nombre que el que le hemos dado, pero acabado en .map, usarlo para obtener nuestros símbolos. No queda más que arrancarlo con la opción -d para comenzar la sesión de depuración:

    m6809-run -d suma.s19
    

    El simulador nos saluda, nos muestra el contenido inicial de los registros y la primera línea de nuestro programa y, cual genio de la lámpara, se queda esperando nuestras órdenes:

    Reading symbols from 'suma.map'...
    PC:0108 CC:_____ A:00 B:00 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0108  <programa        > : LDD   0x0100  <sumando1>
    (dbg) 

    Observad cómo el genio no obtuvo su trabajo por enchufe, sino que es tan listo como para detectar que 0x108 es el inicio del programa y 0x100 es la posición de la variable sumando1. La lástima es que las órdenes que podemos darle no son "unas vacaciones en el Caribe" o un "deportivo de competición". Son mucho más prosaicas. Eso sí, podemos dar tantas órdenes como deseemos. Y es que las cosas adelantan una barbaridad desde los tiempos de Las mil y una noches. Lo primero que le vamos a pedir es que nos liste un poquito del programa:

    (dbg) l
    01:0x0108  <programa        > : LDD   0x0100  <sumando1>
    01:0x010B                     : ADDD  0x0102  <sumando2>
    01:0x010E                     : STD   0x0104  <suma1>
    01:0x0111                     : LDA   0x0101
    01:0x0114                     : ADDA  0x0103
    01:0x0117                     : STA   0x0107
    01:0x011A                     : LDA   0x0100  <sumando1>
    01:0x011D                     : ADCA  0x0102  <sumando2>
    01:0x0120                     : STA   0x0106  <suma2>
    01:0x0123                     : CLRA  
    (dbg) 
    

    Establecemos, a continuación, un punto de ruptura (breakpoint) en la línea situada en 0x111.

    (dbg) b 0x111
    Breakpoint 0 at 01:0x0111                    
    (dbg) 
    

    Significa esto que, cuando pongamos en marcha el simulador, cada vez que la ejecución pase por esa línea, nuestro genio la parará y se quedará esperando a que le demos más órdenes. Pues nada, a ello. Le vamos a decir que continúe con la simulación:

    (dbg) c
    Breakpoint 0 reached.
    PC:0111 CC:_N___ A:99 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0111                     : LDA   0x0101
    (dbg) 
    

    La simulación se ha parado en el punto de ruptura, justo antes de efectuar la suma con el registro A. Podemos seguir el proceso de ejecución, línea a línea, pulsando la tecla s:

    (dbg) s
    PC:0114 CC:_N___ A:90 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0114                     : ADDA  0x0103
    (dbg) s
    PC:0117 CC:____C A:07 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0117                     : STA   0x0107
    (dbg) s
    PC:011A CC:____C A:07 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x011A                     : LDA   0x0100  <sumando1>
    (dbg) s
    PC:011D CC:____C A:21 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x011D                     : ADCA  0x0102  <sumando2>
    (dbg) s
    PC:0120 CC:_N_V_ A:99 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0120                     : STA   0x0106  <suma2>
    (dbg) s
    PC:0123 CC:_N___ A:99 B:07 X:0000 Y:0000 S:0000 U:0000 DP:00
    01:0x0123                     : CLRA  
    (dbg)
    Existen algunas órdenes adicionales como x para examinar la memoria, bl para listar los puntos de ruptura, bd para borrar un determinado punto de ruptura o q para abandonar la simulación:
    (dbg) bl
    Breakpoint 0 at 01:0x0111                    
    (dbg) d 0
    Deleting breakpoint 0
    (dbg) bl
    (dbg) q
    
  4. Ejercicio

    Repetir la prueba anterior, pero restando, en lugar de sumando, dos números de 16 bits.
  5. Ejercicio

    Repetir la primera prueba, pero sumando a un número de 16 bits:
    1. otro de 8 bits sin signo
    2. otro de 8 bits con signo

    Haced el ejercicio con ayuda del registro X en aquel sitio en que lo veáis factible.

    Pista: ya lo dijo el clásico inglés, "SEX or not SEX, that is the question".

  6. Ejercicio

    Con ayuda de la instrucción MUL y el algoritmo de multiplicación tradicional, realícese el mismo ejercicio que la primera prueba pero multiplicando en lugar de sumando: dados dos números enteros sin signo de 16 bits, multiplíquense. Tened en cuenta que el resultado de la multiplicación será un número de 32 bits que podéis almacenar como parte alta y parte baja de 16 bits en memoria.
  7. Órdenes de ensamblador vistas.

    INCx
    incrementa x. x puede ser A o B
    Flags afectados: NZV
    DECx
    decrementa x. x puede ser A o B
    Flags afectados: NZV
    CLRx
    pone x a cero. x puede ser A o B
    Flags afectados: N=V=C=0, Z=1
    NEGx
    cambia a x de signo. x puede ser A o B
    Flags afectados: NZVC, H=?
    INC, DEC, CLR y NEG
    mismas operaciones pero sobre una dirección de memoria
    Flags afectados: igual que en los casos de arriba
    ADDx
    añade al registro x el valor o el contenido de la dirección de memoria especificados. x pueden ser D, A o B
    Flags afectados: HNZVC
    ABX
    añade al registro X el valor del registro B, considerado como número de 8 bits sin signo
    Flags afectados: ninguno
    ADCx
    añade al registro x el valor o el contenido de la dirección de memoria especificados y, además, el valor del bit de acarreo. x pueden ser A o B
    Flags afectados: HNZVC
    SUBx
    resta al registro x el valor o el contenido de la dirección de memoria especificados. x pueden ser D, A o B
    Flags afectados: NZVC, (H=? si x es A o B)
    SBCx
    resta al registro x el valor o el contenido de la dirección de memoria especificados y, además, el valor del bit de acarreo. x pueden ser A o B
    Flags afectados: NZVC, H=?
    SEX
    hace que D tenga el mismo valor con signo que B, considerado también con signo
    Flags afectados: NZ, V=0
    MUL
    multiplica A por B, considerados como números sin signo y el resultado queda en D (sin signo también, como es natural)
    Flags afectados: ZC


  8. Órdenes de la shell relacionadas.

    ls
    lista el contenido de un directorio
    cd
    cambia el directorio de trabajo
    rm
    borra un fichero
    man
    muestra la página de manual de una orden
    cat
    muestra el contenido de un fichero
    echo $?
    muestra el código devuelto por el último programa ejecutado


  9. LPEs.


© 2010 Guillermo González Talaván.