Diseño del programa de lenguaje ensamblador

7

Este es un problema de asignación de tareas e intenté resolverlo todo anoche, pero todavía soy un novato en lenguaje ensamblador.

No me des la solución completa, solo dame una pista.

  

Diseñe un programa de lenguaje de ensamblaje ARM que examinará un 32 bits   el valor almacenado en R1 y cuenta el número de secuencias contiguas de 1s.   Por ejemplo, el valor: 01110001000111101100011100011111 contiene seis   secuencias de 1s.

     

Escriba el valor final en el registro, R2.

Ahora, el algoritmo que creo es leer cada carácter uno por uno y aumentar i en 1 cada vez que se enfrenta a 1 1 continuo. ¿Pero cómo hacerlo en lenguaje ensamblador?

    
pregunta Avnish Gaur

4 respuestas

10

Escriba un bucle para desplazar la palabra hacia la izquierda o hacia la derecha (no importa) hasta que la palabra sea completamente ceros. La bandera de acarreo le da el valor del siguiente bit.

Si carry es 1 y el carry anterior era cero, está comenzando una nueva secuencia de 1 s. A continuación, establezca una marca anterior-was-a-first-one. (Supongo que por contiguo quiere decir al menos 2.)

Si carry es 1 y previous-was-a-first-one se establece, tiene una serie contigua, e incremente su contador. Borra la bandera previous-was-a-first-one .

Si carry es 0 , borre el previous-was-a-first-one .

editar
Al parecer, "contiguo" no requiere más de 1 bit, y luego es aún más simple:

Set 'previous' to '0'.
Shift left until word is all zeros.
If 'carry' = '1' and 'previous' = '0' increment counter.
Set 'previous' to 'carry'.
    
respondido por el stevenvh
1

Aquí hay una solución que itera sobre el número de cadenas, en lugar del número de bits en la palabra. Ya que no estoy realmente familiarizado con el lenguaje ensamblador ARM, lo incluiré en C. Dado que solo utiliza operadores bitwise, se traducirá de manera bastante directa en el código ensamblador.

int nstrings (unsigned long int x)
{
   int result = 0;

   /* convert x into a word that has a '1' for every transition from
    * 0 to 1 or 1 to 0 in the original word.
    */
   x ^= (x << 1);

   /* every pair of ones in the new word represents a string of ones in
    * the original word. Remove them two at a time and keep count.
    */
   while (x) {
     /* remove the lowest set bit from x; this represents the start of a
      * string of ones.
      */
     x &= ~(x & -x);
     ++result;

     /* remove the next set bit from x; this represents the end of that
      * string of ones.
      */
     x &= ~(x & -x);
   }
   return result;
}
    
respondido por el Dave Tweed
1

Sólo sugerencia según lo pedido. Debe pasar a través de cada bit, esto se puede hacer por shifting el número al right . Antes de cambiar, verifique el valor del bit más a la derecha, esto se puede lograr mediante la operación AND con el costant 1 . Use alguna temperatura para almacenar el último valor marcado, para incrementar un contador en el "flanco ascendente", es decir, cuando el valor anterior cambia de 0 a 1, en pseudo código

SET T1=0
SET CNT=0
WHILE INPUT != 0 DO
    IF INPUT AND 1 != 0 AND T1 == 0 INC CNT
    T1 =  INPUT AND 1
    RIGHT SHIFT INPUT
END WHILE
    
respondido por el Felice Pollano
0
  1. Un registro dado X tendrá el resultado. Inicia con cero.
  2. Tome el valor original que se procesará y almacénelo en dos registros, digamos A y B
  3. Gire A hacia la derecha un bit, haga un XOR de A con B, ponga el resultado en A.
  4. Aplique una máscara de 1h a A, poniendo el resultado en B.
  5. Suma B a X.
  6. Desplazar un bit a la derecha y, si no es cero, pasar al paso 4
  7. Divide X entre 2 (muévelo un poco hacia la derecha)

Esto funciona porque el resultado del XOR en el paso 3 tendrá un par de 1 en cada punto en el que hubo una transición. Entonces, si contabilizas cuántos 1 tienes y lo divides por 2, tendrás cuántas transiciones hubo. Lo que te da el número de bloques de valores consecutivos.

Ahora, si X da como resultado 0, tienes todos los 1 o todos los 0. Por lo tanto, puede comenzar por verificar si el valor original es 0 y regresar inmediatamente con cero en tal caso, sin siquiera ejecutar los pasos anteriores. Si no lo es, y X es 0, devuelve 1. Si no, divídelo entre 2 nuevamente (ya que el número de bloques con 1 tiene que ser la mitad del número de bloques distintos, por supuesto).

    
respondido por el fceconel

Lea otras preguntas en las etiquetas