¿Por qué los identificadores cortos crípticos siguen siendo tan comunes en la programación de bajo nivel?

62

Solía haber muy buenas razones para mantener los nombres de instrucción / registro cortos. Esas razones ya no se aplican, pero los nombres crípticos cortos todavía son 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 de TimerCounter1InterruptFlag ), ICR1H (en lugar de InputCapture1High ), DDRB (en lugar de DataDirectionPortB ), etc.
  • Conjunto de instrucciones de .NET CLR (2002): bge.s (en lugar de branch-if-greater-or-equal.short ), etc.

¿No es más fácil trabajar con los nombres más largos y no crípticos?

Al responder y votar, tenga en cuenta lo siguiente. Muchas de las posibles explicaciones que se sugieren aquí se aplican igualmente a la programación de alto nivel, y, sin embargo, el consenso es, en general, utilizar nombres no crípticos que consisten en una palabra o dos (se excluyen las siglas entendidas comúnmente) .

Además, si su argumento principal es sobre espacio físico en un diagrama en papel , tenga en cuenta que esto no se aplica en absoluto al lenguaje ensamblador ni a CIL, y le agradecería que me mostrara un diagrama donde los nombres concisos encajan pero los legibles empeoran el diagrama. Desde la experiencia personal en una empresa de semiconductores fabless, los nombres legibles encajan bien y dan como resultado diagramas más legibles.

¿Cuál es la cosa central que es diferente en la programación de bajo nivel en comparación con los lenguajes de alto nivel que hace que los nombres crípticos concisos sean deseables en la programación de bajo nivel pero no en la de alto nivel ?

    
pregunta Roman Starkov 28.08.2012 - 23:35

11 respuestas

11

Hay tantas ideas diferentes aquí. No puedo aceptar ninguna de las respuestas existentes como respuesta de la : en primer lugar, es probable que haya muchos factores que contribuyen a esto, y en segundo lugar, no puedo saber cuál es el más importante.

Así que aquí hay un resumen de respuestas publicado por otros aquí. Estoy publicando esto como CW y mi intención es marcarlo como aceptado. Por favor, edite si me perdí algo. Intenté 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?

  • Debido a que muchos de ellos son lo suficientemente comunes en el dominio respectivo para garantizar un nombre muy corto. Esto empeora la curva de aprendizaje, pero es una compensación valiosa dada la frecuencia de uso.
  • Debido a que generalmente hay un pequeño conjunto de posibilidades que está arreglado (el programador no puede agregar al conjunto).
  • Porque la legibilidad es una cuestión de hábito y práctica. branch-if-greater-than-or-equal.short es inicialmente más legible que bge.s , pero con algo de práctica la situación se invierte.
  • Debido a que a menudo tienen que escribirse en forma completa, a mano, porque los lenguajes de bajo nivel a menudo no vienen con IDEs poderosos que tengan un buen autocompletado, o un / c no es confiable.
  • Debido a que a veces es conveniente incluir mucha información en el identificador, y un nombre legible sería inaceptablemente largo, incluso para los estándares de alto nivel.
  • Porque así es como se han visto los entornos de bajo nivel históricamente. Romper el hábito requiere un esfuerzo consciente, corre el riesgo de molestar a aquellos a quienes les gustaron las viejas costumbres y debe justificarse como valioso. Seguir con la forma establecida es el "predeterminado".
  • Debido a que muchos de ellos se originan en otros lugares, como esquemas y hojas de datos. Estos, a su vez, se ven afectados por las limitaciones de espacio.
  • Porque las personas a cargo de nombrar las cosas nunca han considerado la legibilidad, o no se dan cuenta de que están creando un problema o son perezosas.
  • Porque en algunos casos los nombres se han convertido en parte de un protocolo para el intercambio de datos, como el uso del lenguaje ensamblador como una representación intermedia de algunos compiladores.
  • Debido a que este estilo es reconocible al instante como de bajo nivel y, por lo tanto, se ve bien para los geeks.

Personalmente creo que algunos de estos no contribuyen realmente a las razones por las que un sistema recientemente desarrollado elegiría este estilo de nombre, pero sentí que sería incorrecto filtrar algunas ideas en este tipo de respuesta.

    
respondido por el Roman Starkov 27.11.2018 - 11:46
105

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 a ese nivel es muy difícil de entender sin la hoja de datos de todos modos, hacer que los nombres de las variables no se puedan buscar es extremadamente inútil.

Eso plantea la pregunta de por qué las hojas de datos usan nombres cortos. Probablemente sea porque a menudo necesita presentar los nombres en tablas como esta, donde no tiene espacio para los identificadores de 25 caracteres:

Además, los esquemas, los diagramas de pines y las serigrafías de PCB a menudo son muy pequeños para el espacio.

    
respondido por el Karl Bielefeldt 28.08.2012 - 23:57
59

Ley de Zipf

Usted mismo puede observar al observar este mismo texto que la longitud de las palabras y la frecuencia de uso están, en general, inversamente relacionadas. Las palabras que se usan con mucha frecuencia, como it , a , but , you y and son muy cortas, mientras que las palabras que se usan con menos frecuencia como observe , comprehension y verbosity son más largos. Esta relación observada entre la frecuencia y la longitud se llama Ley de Zipf .

El número de instrucciones en el conjunto de instrucciones para un microprocesador determinado suele ser de decenas o cientos. Por ejemplo, el conjunto de instrucciones AVM de Atmel parece contener alrededor de cien instrucciones distintas (no conté), pero muchas de ellas son variaciones de un tema común y tienen mnemotécnicas 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 porque los nombres largos toman más tiempo para leer, 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 usará 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 brindarles a los lectores (y escritores) información suficiente 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 AGREGAR, MUL, SUB, LD, ST, BR, NOP, y si no usan esos nombres exactos, usualmente usan nombres que están muy cerca. Una vez que haya aprendido los mnemónicos para un conjunto de instrucciones, no tardará mucho en adaptarse a los conjuntos de instrucciones para otros dispositivos. Por lo tanto, los nombres que le pueden parecer "crípticos" son tan familiares como palabras como and , or y not para programadores expertos en la técnica de la programación de bajo nivel. Creo que la mayoría de las personas que trabajan a nivel de ensamblaje le dirían que aprender a leer el código no es uno de los mayores desafíos en la programación de bajo nivel.

    
respondido por el Caleb 14.01.2013 - 17:19
37

En general

La calidad de los nombres no se trata solo de tener nombres descriptivos, sino que también tiene que considerar otros aspectos, y eso lleva a recomendaciones como:

  • cuanto más global sea el alcance, más descriptivo debe ser el nombre
  • cuanto más se use, más corto debe ser el nombre
  • el mismo nombre debe usarse en todos los contextos para la misma cosa
  • las cosas diferentes deben tener nombres diferentes, incluso si el contexto es diferente
  • las variaciones deben ser detectadas fácilmente
  • ...

Tenga en cuenta que estas recomendaciones son conflictivas.

Nemotécnicas de instrucciones

Como programador de lenguaje ensamblador, usar short-branch-if-greater-or-equal para bge.s me da la misma impresión que cuando veo, como programador de Algol haciendo geometría computacional, SUBSTRACT 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 en lugar de dx := p2.x - p1.x . Simplemente no puedo aceptar que los primeros sean más legibles en los contextos que cuido.

Registrar nombres

Usted elige el nombre oficial de la documentación. La documentación recoge el nombre del diseño. El diseño utiliza muchos formatos gráficos en los que 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 y cuando hablen. Lo saben y usan abreviaturas sistemáticas como TIFR1 para que haya menos posibilidades de confusión. Un punto aquí es que TIFR1 no es una abreviatura aleatoria, es el resultado de un esquema de denominación.

    
respondido por el AProgrammer 29.08.2012 - 09:56
24

Aparte 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 que acceden a los registros, tienden a usar etiquetas iguales o similares a las utilizadas en las hojas de datos de 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 sea probablemente XYZZY1, o si el programador estaba teniendo un buen día, RegXYZZY1.

En cuanto al bge.s , es similar al ensamblador, a las pocas personas que necesitan saber que los nombres más largos son menos legibles. Si no puede hacer que se dirija a bge.s y piense que branch-if-greater-or-equal.short hará una diferencia, simplemente está jugando con el CLR y no lo sabe.

La otra razón por la que verá nombres cortos de variables es que nos permite difundir ampliamente las abreviaturas dentro del dominio al que se dirige el software.

En resumen: se esperan nombres cortos abreviados de variables que reflejan una influencia externa, como las normas de la industria y las hojas de datos de hardware. Los nombres cortos abreviados de variables que son internos al software normalmente son menos deseables.

    
respondido por el mattnz 29.08.2012 - 00:09
10

Voy a echar mi sombrero en este lío.

Las normas y convenciones 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 remanentes de código heredado y procesos de pensamiento antiguos.

Algunos, sin embargo, sirven un propósito. Seguro que BranchGreaterThan sería mucho más legible que BGT , pero ahora hay una convención, es una instrucción y como tal ha ganado un poco de tracción en los últimos 30 años de uso como norma ¿Por qué empezaron con eso? Probablemente un límite de ancho de caracteres arbitrario para instrucciones, variables y demás; ¿Por qué lo mantienen, 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 programado más de un 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, también tienen un propósito. En los diagramas de circuitos, es NO una buena convención para nombrar tus líneas y de manera tan detallada que desordena el diagrama y daña 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 mismas interrupciones también obtienen el mismo nombre para mantener la coherencia para el diseñador incrustado desde el diagrama del circuito hasta el código para programarlo. p>

Un diseñador tiene cierto control sobre esto, pero como en cualquier campo / nuevo idioma, existen convenciones que siguen de hardware a hardware, y como tal deben permanecer 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 probablemente esté cargando un registro < strong> MV probablemente esté moviendo algo de un lugar a otro, no se trata de lo que usted cree 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 usted como debe seguir el diseñador, a menudo no son tan arbitrarios como parecen.

Lo dejo con esto: pedirle a la comunidad integrada que use prácticas verbales de alto nivel es como pedir a los químicos que escriban siempre compuestos químicos. El químico los escribe brevemente para sí mismos y cualquier otra persona en el campo lo entenderá, pero puede tomar un poco de tiempo para que un recién llegado se adapte.

    
respondido por el Jeff Langemeier 14.01.2013 - 15:50
6

Una de las razones por las que utilizan identificadores cortos crípticos es porque no son crípticos para los desarrolladores. Debes darte cuenta de que funcionan todos los días y esos nombres son realmente nombres de dominio. Así que saben de memoria qué significa exactamente TIFR1.

Si llega un nuevo desarrollador al equipo, tendrá que leer las hojas de datos (tal como se explica en @KarlBielefeldt) para que se sientan cómodos con ellas.

Creo que tu pregunta utilizó un mal ejemplo porque, de hecho, en ese tipo de códigos de origen, generalmente ves muchos identificadores criptográficos innecesarios para cosas que no pertenecen al dominio.

Yo diría que principalmente lo hacen debido a los malos hábitos que existían cuando los compiladores no completaron automáticamente todo lo que escribes.

    
respondido por el Alex 29.08.2012 - 15:47
5

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, consulte el artículo de Wikipedia en Acrónimo . Mi respuesta es específica a la programación de bajo nivel.

Causas de nombres crípticos:

  1. Las instrucciones de bajo nivel están fuertemente tipadas
  2. Es necesario que incluya mucha información de tipo en el nombre de una instrucción de bajo nivel
  3. Históricamente, los códigos de un solo carácter se prefieren para empaquetar la información de tipo.

Soluciones y sus inconvenientes:

  1. Hay esquemas modernos de nombres de bajo nivel que son más consistentes que los históricos.
    • LLVM
  2. Sin embargo, todavía existe la necesidad de empaquetar mucha información de tipo.
    • Por lo tanto, las abreviaturas crípticas aún se pueden encontrar en todas partes.
  3. La mejor legibilidad de línea a línea ayudará a un programador principiante de bajo nivel a escoger el lenguaje más rápido, pero no ayudará a comprender grandes partes de código de bajo nivel.

Respuesta completa

(A) Los nombres más largos son posibles. Por ejemplo, los nombres de C ++ SSE2.     Los intrínsecos promedian 12 caracteres en comparación con los 7 caracteres.     En el montaje mnemotécnico.      enlace

(B) La pregunta luego pasa a: ¿Cuánto tiempo / no críptico necesita uno?     para obtener instrucciones de bajo nivel?

(C) Ahora analizamos la composición de dichos esquemas de denominación. Los siguientes son dos esquemas de denominación para la instrucción de bajo nivel misma :

  • Esquema de nombres # 1: CVTSI2SD
  • Esquema de nombres # 2: __m128d _mm_cvtsi32_sd (__m128d a, int b);

(C.1) Las instrucciones de bajo nivel siempre se escriben con fuerza. No puede haber        ambigüedad, inferencia de tipos, conversión automática de tipos, o        sobrecarga (la reutilización del nombre de la instrucción significa operaciones similares pero no equivalentes).

(C.2) Cada instrucción de bajo nivel debe codificar una gran cantidad de información de tipo        en su nombre. Ejemplos de información:

  • Familia de arquitectura
  • Operación
  • Argumentos (entradas) y salidas
  • Tipos (entero con signo, entero sin signo, flotante)
  • Precisión (ancho de bit)

(C.3) Si cada pieza de información se detalla, 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:

  • B significa byte (8 bits)
  • W significa palabra (16 bits)
  • D significa dword "palabra doble" (32 bits)
  • Q significa qword "quad-word" (64 bits)
  • DQ significa dqword "doble palabra cuádruple" (128 bits)

Estas referencias históricas no tenían ningún significado moderno en absoluto, pero aún se mantienen. Un esquema más consistente habría puesto el valor de 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: enlace

(D) Independientemente del esquema de denominación de instrucciones, los programas de bajo nivel son      ya detallado y difícil de entender porque se centran en el      Detalles minuciosos de ejecución. Cambiar el esquema de denominación de instrucciones      mejorará la legibilidad en un nivel de línea a línea, pero no se eliminará      La dificultad de comprender las operaciones de una gran pieza de      código.

    
respondido por el rwong 14.01.2013 - 03:16
2

Los humanos leen y escriben ensamblaje solo ocasionalmente, y la mayoría de las veces es solo un protocolo de comunicación. Es decir, se usa más a menudo como una representación intermedia basada en texto serializado entre el compilador y el ensamblador. Cuanto más detallada sea esta representación, mayor será la sobrecarga innecesaria en este protocolo.

En el caso de los códigos de operación y los nombres de registros, los nombres largos en realidad dañan la legibilidad. Los mnemónicos breves son mejores 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 breves son mejores para los programadores, ya que el código del compilador es más fácil de leer.

    
respondido por el SK-logic 13.01.2013 - 12:31
1

En su mayoría es idiomático. Como @TMN dice en otra parte, así como no escribes import JavaScriptObjectNotation o import HypertextTransferProtocolLibrary en Python, no escribes Timer1LowerHalf = 0xFFFF en C. Parece igualmente ridículo en 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 embebidos se desvían del lenguaje estándar y la sintaxis para implementar características más útiles para la programación embebida. 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 para analizar el código. De ahí la utilidad de los 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. Usted podría declarar:

volatile char MAGIC_REGISTER @ 0x7FFFABCD;

Ahora, el único IDE en existencia que analizará esto es el propio IDE de HiTech ( HiTide ). En cualquier otro editor, tendrás que escribirlo manualmente, desde la memoria, cada vez. Esto envejece muy rápidamente.

Luego también está el hecho de que cuando utiliza 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 tienes que expandir la columna de nombre a 13 caracteres para ver la diferencia entre dos registros y jugar "detectar la diferencia" en docenas de líneas de palabras repetidas.

Esto puede parecer una tontería, pero ¿no están diseñadas todas las convenciones de codificación para reducir la fatiga ocular, disminuir la tipificación superflua o abordar alguna otra de un millón de pequeñas quejas?

    
respondido por el detly 14.01.2013 - 02:44
1

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:

  1. Los antecedentes científicos del programador.
  2. Las habilidades de programación del programador.
  3. El entorno del programador.

Creo que no sirve de nada discutir sobre la programación de bajo o alto nivel. Al final, siempre se puede fijar 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 denominaciones "convenciones". A menudo están atrapados en su dominio y utilizan las abreviaturas conocidas sin pensar en la legibilidad o en 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 código comprensible. Es como el fuego y el olvido.

Una explicación del tercer aspecto: Es poco probable que rompa con las convenciones de su entorno, que pueden ser el código antiguo que debe soportar, los estándares de codificación de su empresa (administrados por economistas que no se preocupan por la codificación) o el dominio al que pertenece. Si alguien comenzó a usar nombres crípticos y tiene que admitirlo 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 su propio estándar. Y por último, si está rodeado de usuarios de dominio, no comenzará a escribir otro idioma del que ellos usan.

    
respondido por el pwagner 15.01.2013 - 08:42

Lea otras preguntas en las etiquetas