Pregunta

Necesito optimizar el código para tener espacio para algún código nuevo. No tengo espacio para todos los cambios. No puedo usar el cambio de banco de código (80c31 con 64k).

¿Fue útil?

Solución

Realmente no has dado mucho para seguir aquí, pero hay dos niveles principales de optimizaciones que puedes considerar:

Micro optimizaciones:   p.ej. XOR A en lugar de MOV A, 0   Adam ha cubierto algunos de estos muy bien anteriormente.

Macro-Optimizaciones:   Observe la estructura de su programa, las estructuras de datos y los algoritmos utilizados, las tareas realizadas, y piense MUY bien en cómo podrían reorganizarse o incluso eliminarse. ¿Hay fragmentos enteros de código que en realidad no se usan? ¿Está su código lleno de declaraciones de salida de depuración que el usuario nunca ve? ¿Hay funciones específicas para un solo cliente que podría dejar fuera de una versión general?

Para manejarlo bien, necesitará averiguar DONDE se está utilizando su memoria. El mapa de Linker es un buen lugar para comenzar con esto. Las macro optimizaciones son donde se pueden hacer las GRANDES victorias.

Como comentario aparte, podría, en serio, intentar reescribir partes de su código con un buen compilador C optimizador. Puede que te sorprenda lo apretado que puede ser el código. Un verdadero hotshot de ensamblador puede mejorarlo, pero puede ser fácilmente mejor que la mayoría de los codificadores. Utilicé el IAR hace unos 20 años, y me voló los calcetines.

Otros consejos

Con el lenguaje ensamblador, tendrá que optimizar a mano. Aquí hay algunas técnicas:

Nota: IANA8051P (no soy un programador 8501 pero he realizado muchos ensamblados en otros chips de 8 bits).

Revisa el código en busca de bits duplicados, sin importar cuán pequeños sean y haz que funcionen.

Aprenda algunas de las instrucciones más inusuales y vea si puede usarlas para optimizar, por ejemplo. Un buen truco es usar XOR A para limpiar el acumulador en lugar de MOV A, 0: ahorra un byte.

Otro buen truco es que si llamas a una función antes de regresar, salta a ella, por ejemplo, en lugar de:

CALL otherfunc
RET

Solo haz:

JMP otherfunc

Asegúrese siempre de realizar saltos y ramas relativas siempre que sea posible, ya que usan menos memoria que los saltos absolutos.

Eso es todo lo que puedo pensar en mi cabeza por el momento.

Lo siento, estoy llegando tan tarde, pero una vez tuve exactamente el mismo problema, y ??se convirtió en un problema repetido que seguía volviendo a mí. En mi caso, el proyecto era un teléfono, en un procesador familiar 8051, y había agotado totalmente la memoria ROM (código). Seguía volviendo a mí porque la administración seguía solicitando nuevas características, por lo que cada nueva característica se convirtió en un proceso de dos pasos. 1) Optimice las cosas viejas para hacer espacio 2) Implemente la nueva función, usando el espacio que acabo de hacer.

Hay dos enfoques para la optimización. Táctico y Estratégico. Las optimizaciones tácticas ahorran algunos bytes a la vez con una idea de micro optimización. Creo que necesita optimizaciones estratégicas que implican un replanteamiento más radical sobre cómo está haciendo las cosas.

Algo que recuerdo funcionó para mí y podría funcionar para usted;

Mire la esencia de lo que tiene que hacer su código e intente destilar algunas operaciones primitivas flexibles realmente fuertes. Luego reconstruya su código de nivel superior para que no haga nada de nivel bajo excepto llamar a las primitivas. Idealmente use un enfoque basado en tablas, su tabla contiene cosas como; Estado de entrada, evento, estado de salida, primitivas ... En otras palabras, cuando ocurre un evento, busque una celda en la tabla para ese evento en el estado actual. Esa celda le dice a qué nuevo estado cambiar (opcionalmente) y qué primitivo (s) (si corresponde) ejecutar. Es posible que necesite varios conjuntos de estados / eventos / tablas / primitivas para diferentes capas / subsistemas.

Uno de los muchos beneficios de este enfoque es que puede pensarlo como un lenguaje personalizado para su problema particular, en el que puede crear de manera muy eficiente (es decir, con un código adicional mínimo) una nueva funcionalidad simplemente modificando la tabla.

Lo siento, llegué meses tarde y de todos modos probablemente no tuviste tiempo para hacer algo tan radical. Por lo que sé, ¡ya estabas usando un enfoque similar! Pero mi respuesta podría ayudar a alguien más algún día que lo sepa.

En el departamento de caídas, también podría considerar comprimir parte de su código y mantener solo una parte que se usa activamente descomprimida en un momento determinado. Me resulta difícil creer que el código requerido para el sistema de compresión / descompresión sería una porción suficientemente pequeña de la pequeña memoria del 8051 para que esto valga la pena, pero ha funcionado de maravilla en sistemas un poco más grandes.

Otro enfoque más es recurrir a un formato de código de bytes o el tipo de código controlado por tablas que generan algunas herramientas de máquina de estado: hacer que una máquina entienda lo que está haciendo su aplicación y generar una implementación completamente incomprensible puede ser una excelente opción. forma de ahorrar espacio :)

Finalmente, si el código se compila en C, sugeriría compilar con una gama de opciones diferentes para ver qué sucede. Además, escribí un artículo sobre codificación C compacta para el ESC en 2001 eso sigue siendo bastante actual. Vea ese texto para otros trucos para máquinas pequeñas.

1) Donde sea posible, guarde sus variables en Idata, no en xdata
2) Mire sus declaraciones Jmp & # 8211; hacer uso de SJmp y AJmp

Supongo que sabes que no encajará porque escribiste / cumpliste y sacaste el " de memoria " error. :) Parece que las respuestas abordan su pregunta con bastante precisión; antes de obtener ejemplos de código.

Sin embargo, recomendaría algunas ideas adicionales;

  1. Asegúrese de que todo el código sea realmente siendo utilizado - prueba de cobertura de código? Un Sub no utilizado es una gran victoria - esta es una paso difícil: si eres el original autor, puede ser más fácil - (bueno, tal vez) :)
  2. Asegure el nivel de " verificación " e inicialización - a veces nosotros tener una tendencia a ser demasiado celoso al asegurarnos hemos inicializado variables / memoria y efectivamente con razón, ¿cuántas veces hemos ha sido mordido por eso. No digo no inicializar (duh), pero si lo estamos haciendo un movimiento de memoria, el destino no necesita tener cero primero - esto encaja con

    1 -

  3. Evalúe las nuevas funciones: ¿puede un sub existente se mejorará para cubrir ambas funciones o tal vez una característica existente reemplazada?
  4. Divide el código grande si una parte del el código grande puede guardar crear un nuevo pequeño código.

o tal vez hay un argumento para la versión de hardware 2.0 en la tabla ahora ... :)

saludos

Además de las optimizaciones obvias ya mencionadas (más o menos), aquí hay una realmente extraña (y casi imposible de lograr): reutilización de código. Y con la reutilización de Código no me refiero a la reutilización normal, sino a a) reutilizar su código como datos ob) reutilizar su código como otro código. Tal vez pueda crear un lut (o cualquier dato estático) que pueda representar mediante los códigos de operación hexadecimales asm (aquí debe buscar la arquitectura harvard vs von neumann).

El otro reutilizaría el código dándole al código un significado diferente cuando lo abordes de manera diferente. Aquí un ejemplo para aclarar lo que quiero decir. Si los bytes de su código se ven así: AABCCCDDEEFFGGHH en la dirección X donde cada letra representa un código de operación, imagine que ahora saltaría a X + 1. Tal vez obtenga una funcionalidad completamente diferente donde los bytes separados por espacio ahora forman los nuevos códigos de operación: ABC CCD DE EF GH.

Pero cuidado: esto no solo es difícil de lograr (tal vez es imposible), sino que es un horror mantenerlo. Entonces, si no es un código de demostración (o algo similar exótico), recomendaría usar las otras formas ya mencionadas para guardar mem.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top