Solía haber muy buenas razones para mantener cortos los nombres de instrucción / registro. Esas razones ya no se aplican, pero los nombres crípticos cortos siguen siendo muy comunes en la programación de bajo nivel.
¿Por qué es esto? ¿Es solo porque los viejos hábitos son difíciles de romper o hay mejores razones?
Por ejemplo:
- Atmel ATMEGA32U2 (2010?):
TIFR1
(En lugar deTimerCounter1InterruptFlag
),ICR1H
(en lugar deInputCapture1High
),DDRB
(en lugar deDataDirectionPortB
), etc. - Conjunto de instrucciones .NET CLR (2002):
bge.s
(en lugar debranch-if-greater-or-equal.short
), etc.
¿No son los nombres largos y no crípticos más fáciles de trabajar?
Al responder y votar, tenga en cuenta lo siguiente. Muchas de las posibles explicaciones sugeridas aquí se aplican igualmente a la programación de alto nivel, y, sin embargo, el consenso, en general, es usar nombres no crípticos que consisten en una o dos palabras (excluidas las siglas comúnmente entendidas).
Además, si su argumento principal es sobre el espacio físico en un diagrama en papel , tenga en cuenta que esto no se aplica en absoluto al lenguaje ensamblador o CIL, además le agradecería que me muestre un diagrama donde los nombres concisos se ajustan pero los legibles empeoran el diagrama. . Por experiencia personal en una compañía de semiconductores sin fábrica, los nombres legibles encajan perfectamente y dan como resultado diagramas más legibles.
¿Cuál es la cosa principal que es diferente acerca de la programación de bajo nivel en comparación con lenguajes de alto nivel que hace que los nombres crípticos lacónicas deseables de bajo nivel, pero no de programación de alto nivel?
fuente
JSR
es tres veces más largo que el código de operación que representa ($20
en un 6502) y considerablemente más fácil de entender de un vistazo.set Accumulator32 to BaseIndex32
¿ Intentar ? Simplemente expandir las abreviaturas tradicionales no es la única forma de hacer que algo sea más legible.Respuestas:
La razón por la que el software usa esos nombres es porque las hojas de datos usan esos nombres. Dado que el código en ese nivel es muy difícil de entender sin la hoja de datos de todos modos, hacer nombres de variables que no puede buscar es extremadamente inútil.
Eso plantea la pregunta de por qué las hojas de datos usan nombres cortos. Probablemente se deba a que a menudo necesita presentar los nombres en tablas como esta donde no tiene espacio para identificadores de 25 caracteres:
Además, cosas como esquemas, diagramas de pines y serigrafías de PCB a menudo son muy estrechas para el espacio.
fuente
Ley de Zipf
Usted mismo puede observar al mirar este mismo texto que la longitud de las palabras y la frecuencia de uso están, en general, inversamente relacionadas. Las palabras que se utilizan con mucha frecuencia, como
it
,a
,but
,you
, yand
son muy cortos, mientras que las palabras que se utilizan con menos frecuencia les gustaobserve
,comprehension
yverbosity
son más largos. Esta relación observada entre frecuencia y longitud se llama Ley de Zipf .El número de instrucciones en el conjunto de instrucciones para un microprocesador dado suele ser de docenas o cientos. Por ejemplo, el conjunto de instrucciones Atmel AVR parece contener alrededor de un centenar de instrucciones distintas (no conté), pero muchas de ellas son variaciones sobre un tema común y tienen mnemónicos muy similares. Por ejemplo, las instrucciones de multiplicación incluyen MUL, MULS, MULSU, FMUL, FMULS y FMULSU. No tiene que mirar la lista de instrucciones por mucho tiempo antes de tener la idea general de que las instrucciones que comienzan con "BR" son ramas, las instrucciones que comienzan con "LD" son cargas, etc. Lo mismo se aplica a las variables: Incluso los procesadores complejos proporcionan solo un número limitado de lugares para almacenar valores: registros de condición, registros de propósito general, etc.
Debido a que hay muy pocas instrucciones y a que los nombres largos tardan más en leerse, tiene sentido darles nombres cortos. Por el contrario, los lenguajes de nivel superior permiten a los programadores crear una gran cantidad de funciones, métodos, clases, variables, etc. Cada uno de estos se utilizará con mucha menos frecuencia que la mayoría de las instrucciones de ensamblaje, y los nombres más largos y descriptivos son cada vez más importantes para dar a los lectores (y escritores) suficiente información para comprender qué son y qué hacen.
Además, los conjuntos de instrucciones para diferentes procesadores a menudo usan nombres similares para operaciones similares. La mayoría de los conjuntos de instrucciones incluyen operaciones para ADD, MUL, SUB, LD, ST, BR, NOP, y si no usan esos nombres exactos, generalmente usan nombres que están muy cerca. Una vez que haya aprendido la mnemotecnia para un conjunto de instrucciones, no tardará mucho en adaptarse a los conjuntos de instrucciones para otros dispositivos. Así que los nombres que podrían parecer "críptica" a que son casi tan familiar como palabras como
and
,or
ynot
a los programadores que son expertos en el arte de la programación de bajo nivel. Creo que la mayoría de las personas que trabajan en el nivel de ensamblado le diría que aprender a leer el código no es uno de los mayores desafíos en la programación de bajo nivel.fuente
En general
La calidad de los nombres no se trata solo de tener nombres descriptivos, sino que también debe considerar otros aspectos, y eso lleva a recomendaciones como:
Tenga en cuenta que estas recomendaciones son contradictorias.
Instrucción mnemónica
Como programador de lenguaje ensamblador, usar
short-branch-if-greater-or-equal
forbge.s
me da la misma impresión que cuando veo, como un programador Algol haciendo geometría computacional, enSUBSTRACT THE-HORIZONTAL-COORDINATE-OF-THE-FIRST-POINT TO THE-HORIZONTAL-COORDINATE-OF-THE-SECOND-POINT GIVING THE-DIFFERENCES-OF-THE-COORDINATE-OF-THE-TWO-POINTS
lugar dedx := p2.x - p1.x
. Simplemente no puedo aceptar que los primeros sean más legibles en los contextos que me interesan.Registrar nombres
Elige el nombre oficial de la documentación. La documentación elige el nombre del diseño. El diseño utiliza muchos formatos gráficos donde los nombres largos no son adecuados y el equipo de diseño vivirá con esos nombres durante meses, si no años. Por ambas razones, no usarán "Indicador de interrupción del primer contador de temporizador", lo abreviarán en su esquema así como cuando hablen. Lo saben y usan abreviaturas sistemáticas como
TIFR1
para que haya menos posibilidades de confusión. Un punto aquí es queTIFR1
no es una abreviatura aleatoria, es el resultado de un esquema de nombres.fuente
TIFR1
realmente un mejor esquema de nombres de loInterruptFlag1
que es, oIptFlag1
si realmente tiene que ser breve?InterruptFlag
yIptFlag
son mejores queIF
de la misma manera queEnumerableInterface
yItfcEnumerable
son mejores queIEnumerable
.InterruptFlag1
por razones de mayor claridad.Además de las razones de los "viejos hábitos", el código heredado que se escribió hace 30 años y todavía está en uso es muy común. A pesar de lo que piensan algunas personas menos experimentadas, refactorizar estos sistemas para que se vean bonitos tiene un costo muy alto por una pequeña ganancia y no es comercialmente viable.
Los sistemas integrados que están cerca del hardware, y al acceder a los registros, tienden a usar las mismas etiquetas o etiquetas similares a las utilizadas en las hojas de datos del hardware, por muy buenas razones. Si el registro se llama XYZZY1 en las hojas de datos de hardware, tiene sentido que la Variable que lo representa probablemente sea XYZZY1, o si el programador estaba teniendo un buen día, RegXYZZY1.
En cuanto a
bge.s
, es similar al ensamblador: para las pocas personas que necesitan saberlo, los nombres más largos son menos legibles. Si no puede entenderlobge.s
y piensabranch-if-greater-or-equal.short
que hará la diferencia, simplemente está jugando con el CLR y no lo sabe.La otra razón por la que verá nombres cortos de variables se debe a la amplia difusión de abreviaturas dentro del dominio al que apunta el software.
En resumen: se esperan nombres abreviados cortos de variables que reflejen una influencia externa, como las normas de la industria y las hojas de datos de hardware. Los nombres cortos de variables abreviadas que son internos al software normalmente son menos deseables.
fuente
TIFR1
es más legible para aquellos que necesitan saberlo queTimerCounter1InterruptFlag
correcto?j?
instrucciones . Tener una instrucción más obviamente nombrada definitivamente me ayudaría. Pero tal vez soy la excepción más que la regla. Tengo problemas para recordar detalles triviales.Hay tantas ideas diferentes aquí. No puedo aceptar ninguna de las respuestas existentes como la respuesta: en primer lugar, es probable muchos factores que contribuyen a esto, y en segundo lugar, no puede saber cuál es el más significativo.
Así que aquí hay un resumen de las respuestas publicadas por otros aquí. Estoy publicando esto como CW y mi intención es eventualmente marcarlo como aceptado. Edite si me perdí algo. Traté de reformular cada idea para expresarla de manera concisa pero clara.
Entonces, ¿por qué los identificadores cortos crípticos son tan comunes en la programación de bajo nivel?
branch-if-greater-than-or-equal.short
es inicialmente más legible quebge.s
, pero con algo de práctica la situación se revierte.Personalmente, creo que algunos de estos no contribuyen realmente a las razones por las que un sistema recientemente desarrollado elegiría este estilo de nomenclatura, pero sentí que sería un error filtrar algunas ideas en este tipo de respuesta.
fuente
Voy a tirar mi sombrero en este desastre.
Las convenciones y estándares de codificación de alto nivel no son lo mismo que las normas y prácticas de codificación de bajo nivel. Desafortunadamente, la mayoría de ellos son restos del código heredado y los viejos procesos de pensamiento.
Algunos, sin embargo, tienen un propósito. Claro, BranchGreaterThan sería mucho más legible que BGT , pero hay una convención allí ahora, es una instrucción y, como tal, ha ganado algo de tracción en los últimos 30 años de uso como estándar. Por qué empezaron con él, probablemente algún límite de ancho de caracteres arbitrario para instrucciones, variables y demás; por qué lo guardan, es un estándar. Este estándar es el mismo que usar int como identificador, sería más legible usar Integer en todos los casos, pero es necesario para cualquier persona que haya estado programando más de unas pocas semanas ... no. ¿Por qué? Porque es una práctica estándar.
En segundo lugar, como dije en mi comentario, muchas de las interrupciones se llaman INTG1 y otros nombres crípticos, estos también tienen un propósito. En los diagramas de circuito NO es una buena convención nombrar sus líneas y, de manera tan vergonzosa, satura el diagrama y perjudica la legibilidad. Toda la verbosidad se maneja en la documentación. Y dado que todos los diagramas de cableado / circuito tienen estos nombres cortos para líneas de interrupción, las interrupciones en sí mismas también reciben el mismo nombre para mantener la coherencia para el diseñador incorporado desde el diagrama de circuito hasta el código para programarlo.
Un diseñador tiene cierto control sobre esto, pero al igual que cualquier campo / lenguaje nuevo, existen convenciones que se siguen de hardware a hardware, y como tal deberían mantenerse similares en cada lenguaje ensamblador. Puedo ver un fragmento de ensamblaje y ser capaz de obtener la esencia del código sin usar ese conjunto de instrucciones porque se adhieren a una convención, LDA o alguna relación con él, probablemente esté cargando un registro MV probablemente está moviendo algo de algún lado a en otro lugar, no se trata de lo que crees que es bueno o es una práctica de alto nivel, es un lenguaje en sí mismo y, como tal, tiene sus propios estándares y significa que tú, como diseñador, debes seguirlos, a menudo no son tan arbitrarios como ellos parecen.
Te dejo con esto: pedirle a la comunidad integrada que use prácticas detalladas de alto nivel es como pedirles a los químicos que siempre escriban compuestos químicos. El químico los escribe cortos para sí mismos y cualquier otra persona en el campo lo entenderá, pero puede tomar un poco de tiempo para adaptarse.
fuente
Una razón por la que usan identificadores cortos crípticos es porque no son crípticos para los desarrolladores. Tienes que darte cuenta de que trabajan con él todos los días y esos nombres son realmente nombres de dominio. Entonces saben de memoria qué significa exactamente TIFR1.
Si un nuevo desarrollador llega al equipo, tendrá que leer las hojas de datos (como lo explicó @KarlBielefeldt) para que se sientan cómodos con ellas.
Creo que su pregunta usó un mal ejemplo porque, de hecho, en ese tipo de códigos fuente generalmente se ven muchos identificadores de criptas innecesarios para cosas que no son de dominio.
Diría que lo hacen principalmente debido a los malos hábitos que existían cuando los compiladores no completaban automáticamente todo lo que escribía.
fuente
Resumen
El inicialismo es un fenómeno generalizado en muchos círculos técnicos y no técnicos. Como tal, no se limita a la programación de bajo nivel. Para la discusión general, vea el artículo de Wikipedia sobre acrónimo . Mi respuesta es específica para la programación de bajo nivel.
Causas de nombres crípticos:
Soluciones y sus inconvenientes:
Respuesta completa
(A) Los nombres más largos son posibles. Por ejemplo, los nombres de los intrínsecos C ++ SSE2 promedian 12 caracteres en comparación con los 7 caracteres en el mnemónico de ensamblaje. http://msdn.microsoft.com/en-us/library/c8c5hx3b(v=vs.80).aspx
(B) La pregunta pasa a: ¿Cuánto tiempo / no críptico necesita uno para obtener instrucciones de bajo nivel?
(C) Ahora analizamos la composición de tales esquemas de nombres. Los siguientes son dos esquemas de nombres para la misma instrucción de bajo nivel:
CVTSI2SD
__m128d _mm_cvtsi32_sd (__m128d a, int b);
(C.1) Las instrucciones de bajo nivel siempre se escriben fuertemente. No puede haber ambigüedad, inferencia de tipos, conversión automática de tipos o sobrecarga (reutilización del nombre de la instrucción para significar operaciones similares pero no equivalentes).
(C.2) Cada instrucción de bajo nivel debe codificar mucha información de tipo en su nombre. Ejemplos de información:
(C.3) Si se detalla cada pieza de información, el programa será más detallado.
(C.4) Los esquemas de codificación de tipo utilizados por varios proveedores tenían largas raíces históricas. Como ejemplo, en el conjunto de instrucciones x86:
Estas referencias históricas no tenían ningún significado moderno, pero aún se mantienen. Un esquema más consistente habría puesto el valor del ancho de bits (8, 16, 32, 64, 128) en el nombre.
Por el contrario, LLVM es un paso correcto en la dirección de la coherencia en las instrucciones de bajo nivel: http://llvm.org/docs/LangRef.html#functions
(D) Independientemente del esquema de nomenclatura de instrucciones, los programas de bajo nivel ya son detallados y difíciles de entender porque se centran en los detalles minuciosos de la ejecución. Cambiar el esquema de nomenclatura de instrucciones mejorará la legibilidad en un nivel de línea a línea, pero no eliminará la dificultad de comprender las operaciones de un gran código.
fuente
CVTSI2SD
no lleva más información queConvertDword2Double
oConvInt32ToFloat64
, pero este último, aunque más largo, es reconocible al instante, mientras que el primero debe ser descifrado ...Los humanos leen y escriben ensamblajes solo ocasionalmente, y la mayoría de las veces es solo un protocolo de comunicación. Es decir, se usa con mayor frecuencia como una representación intermedia basada en texto serializado entre el compilador y el ensamblador. Cuanto más detallada es esta representación, más sobrecarga innecesaria se encuentra en este protocolo.
En el caso de códigos de operación y nombres de registro, los nombres largos realmente dañan la legibilidad. La mnemotecnia corta es mejor para un protocolo de comunicación (entre compilador y ensamblador), y el lenguaje ensamblador es un protocolo de comunicación la mayor parte del tiempo. Los mnemónicos cortos son mejores para los programadores, ya que el código del compilador es más fácil de leer.
fuente
TIFR
, o tienden a contener palabras completas?Sobre todo es idiomático. Como @TMN dice en otra parte, así como no escribes
import JavaScriptObjectNotation
oimport HypertextTransferProtocolLibrary
en Python, no escribesTimer1LowerHalf = 0xFFFF
en C. Parece igualmente ridículo en su contexto. Todos los que necesitan saber ya lo saben.La resistencia al cambio puede surgir, en parte, del hecho de que algunos proveedores de compiladores de C para sistemas integrados se desvían del estándar y la sintaxis del lenguaje para implementar funciones más útiles para la programación integrada. Esto significa que no siempre puede usar la función de autocompletar de su IDE favorito o editor de texto al escribir código de bajo nivel, porque estas personalizaciones anulan su capacidad de analizar código. De ahí la utilidad de nombres de registro cortos, macros y constantes.
Por ejemplo, el compilador C de HiTech incluía una sintaxis especial para las variables que necesitaban tener una posición especificada por el usuario en la memoria. Puedes declarar:
Ahora, el único IDE existente que analizará esto es el propio IDE de HiTech ( HiTide ). En cualquier otro editor, tendrá que escribirlo manualmente, desde la memoria, cada vez. Esto envejece muy rápido.
Luego también está el hecho de que cuando usa herramientas de desarrollo para inspeccionar registros, a menudo se muestra una tabla con varias columnas (nombre de registro, valor en hexadecimal, valor en binario, último valor en hexadecimal, etc.). Los nombres largos significan que debe expandir la columna del nombre a 13 caracteres para ver la diferencia entre dos registros y jugar a "detectar la diferencia" en docenas de líneas de palabras repetidas.
Esto puede sonar como pequeñas tonterías tontas, pero ¿no están todas las convenciones de codificación diseñadas para reducir la fatiga visual, disminuir el tipeo superfluo o abordar una de las millones de pequeñas quejas?
fuente
File.ReadAllBytes
también puede parecer ridículamente largo para alguien acostumbradofread
. Entonces ... ¿por qué tratar el código de alto y bajo nivel de manera diferente ?Timer1InterruptFlag
,Timer2InterruptFlag
, ...,Timer9InterruptFlag
,IOPortAToggleMask
,IOPortBToggleMask
, etc x100. En un lenguaje de nivel superior, usarías variables que difieren mucho más ... o usarías más estructura.Timer1InterruptFlag
es un 75% de ruido irrelevante en comparación conT1IF
. No creo que cree una gran lista de variables en C # que apenas difieran así.UARTEnable(UART1, BITS_8, PARITY_N, STOP_1, BAUD_115200)
. Pero todavía son increíblemente torpes e implican mucha indirección e ineficiencia. Intento usarlos siempre que sea posible, pero la mayoría de las veces, envuelvo la manipulación del registro en mis propias funciones y la llamo desde la lógica de nivel superior.set_prescalar(TMR4,13);
es en mi humilde opinión mucho menos claro de lo que seríaTMR4->PSREG=12;
. Incluso si uno mira el manual del compilador para averiguar qué hace el primer código, probablemente todavía tendrá que ...Me sorprende que nadie haya mencionado la pereza y que no se discutan otras ciencias. Mi trabajo diario como programador me muestra que las convenciones de nomenclatura para cualquier tipo de variable en un programa están influenciadas por tres aspectos diferentes:
Creo que no sirve de nada discutir sobre programación de bajo o alto nivel. Al final, siempre se puede precisar a los tres aspectos anteriores.
Una explicación del primer aspecto: muchos "programadores" no son programadores en primer lugar. Son matemáticos, físicos, biólogos o incluso psicólogos o economistas, pero muchos de ellos no son informáticos. La mayoría de ellos tienen sus propias palabras clave y abreviaturas específicas de dominio que puede ver en sus "convenciones" de nombres. A menudo están atrapados en su dominio y usan esas abreviaturas conocidas sin pensar en la legibilidad o las guías de codificación.
Una explicación del segundo aspecto: como la mayoría de los programadores no son informáticos, sus habilidades de programación son limitadas. Es por eso que a menudo no les importan las convenciones de codificación, sino más bien las convenciones específicas de dominio como se indica como primer aspecto. Además, si no tiene las habilidades de un programador, no tiene la comprensión de las convenciones de codificación. Creo que la mayoría de ellos no ven la necesidad urgente de escribir un código comprensible. Es como fuego y olvidar.
Una explicación del tercer aspecto: es poco probable que rompa con las convenciones de su entorno, que pueden ser códigos antiguos que debe admitir, estándares de codificación de su empresa (administrados por economistas a quienes no les importa la codificación) o el dominio al que pertenece. Si alguien comenzó a usar nombres crípticos y usted tiene que apoyarlo a él o su código, es poco probable que cambie los nombres crípticos. Si no hay estándares de codificación en su empresa, apuesto a que casi todos los programadores escribirán sus propios estándares. Y por último, si está rodeado de usuarios de dominio, no comenzará a escribir otro idioma del que usan.
fuente