¿Por qué no se escriben los programas en la Asamblea con más frecuencia? [cerrado]


216

Parece ser una opinión generalizada que la programación de ensamblaje lleva más tiempo y es más difícil de programar que un lenguaje de nivel superior como C. Por lo tanto, parece recomendarse o asumir que es mejor escribir en un lenguaje de nivel superior por estas razones. y por la mejor portabilidad.

Recientemente he estado escribiendo en ensamblaje x86 y me di cuenta de que quizás estas razones no son realmente ciertas, excepto quizás la portabilidad. Quizás es más una cuestión de familiaridad y saber cómo escribir bien el ensamblaje. También noté que la programación en ensamblaje es bastante diferente a la programación en un HLL. Quizás un programador de ensamblaje bueno y experimentado podría escribir programas con la misma facilidad y rapidez que un programador de C experimentado escribiendo en C.

Quizás sea porque la programación de ensamblaje es bastante diferente a las HLL y, por lo tanto, requiere diferentes formas de pensar, métodos y formas, lo que hace que parezca muy incómodo programar para personas desconocidas, por lo que le da su mal nombre para escribir programas.

Si la portabilidad no es un problema, entonces, ¿qué tendría C sobre un buen ensamblador como NASM?

Editar: solo para señalar. Cuando escribe en conjunto, no tiene que escribir solo en códigos de instrucciones. Puede usar macros y procedimientos y sus propias convenciones para hacer varias abstracciones para hacer que los programas sean más modulares, más fáciles de mantener y más fáciles de leer. Aquí es donde entra familiarizarse con cómo escribir un buen ensamblaje.


71
Escribir ? ¿Qué hay de leer el código? usted (y otros) leerán el código mucho más de lo que lo escriben
nos

81
¿Por qué debería tener que aprender un nuevo idioma solo porque mi programa se ejecutará en una nueva plataforma? ¿Por qué debería tener que construir mis programas para que se ajusten a la idea de CPU de cuántos registros hay y qué puede hacer con ellos? Trato de resolver los problemas, no las ofertas de las computadoras.
Joachim Sauer

8
Resumen de EDIT: se puede usar un compilador de C.
Meinersbur

44
@Simon Quizás tenga mis años equivocados entonces, pero me sorprende que estemos debatiendo ASM contra "un lenguaje de alto nivel como C" en 2010. Específicamente, la parte donde C es el ejemplo de un lenguaje de alto nivel
matt b

11
@changelog: Así no se deletrea programación.reddit.com.
BoltClock

Respuestas:


331

ASM tiene poca legibilidad y no es realmente fácil de mantener en comparación con los lenguajes de nivel superior.

Además, hay muchos menos desarrolladores de ASM que para otros lenguajes más populares, como C.

Además, si usa un lenguaje de nivel superior y las nuevas instrucciones ASM están disponibles (SSE, por ejemplo), solo necesita actualizar su compilador y su antiguo código puede hacer uso fácilmente de las nuevas instrucciones.

¿Qué pasa si la próxima CPU tiene el doble de registros?

Lo contrario de esta pregunta sería: ¿Qué funcionalidad proporcionan los compiladores?

Dudo que pueda / quiera / deba optimizar su ASM mejor que la gcc -O3lata.


10
gcc no es tan bueno en la optimización, mucho mejor que el humano promedio, pero hay muchos lugares donde los optimizadores no hacen un buen trabajo. Estoy de acuerdo contigo aunque de otra manera.
old_timer

44
@dwelch En casos muy raros, gcc (o muchos otros compiladores) no logran optimizar correctamente el C. compilado. En esos casos, sin embargo, siempre puede escribir un número limitado de procedimientos en ASM y vincular solo esos métodos durante la compilación.
cortijon

@Ben S: inicialmente edité en "muchos" en lugar de "mucho" porque "mucho" se usa solo para objetos singulares. Dado que el objeto de "mucho" es plural (desarrolladores), "muchos" es la opción correcta. Pero no volveré a editar tu respuesta si "mucho" es lo que quieres.
Billy ONeal

1
Hay muchos casos en los que un compilador no puede optimizar bien, pero a menudo un desarrollador que conoce las limitaciones del optimizador puede optimizar su código C sin recurrir al ensamblaje.
Qwertie

1
FWIW en mi trabajo diario compilo nuestro producto con gcc -g -O0, porque poder adjuntarle gdb en un sistema en vivo y no volverse loco debido a las variables optimizadas de la existencia, vale mucho más para el compañía de lo que sería dejar otros 4 mil millones de ciclos de CPU inactivos todos los días (de un total de 3 billones). Crujir enteros no es el cuello de botella con mucha frecuencia.
Bernd Jendrissek

1930

Demonios, soy un compilador.

Acabo de escanear miles de líneas de código mientras leías esta oración. Navegué a través de millones de posibilidades de optimizar una sola línea suya utilizando cientos de técnicas de optimización diferentes basadas en una gran cantidad de investigación académica a la que pasaría años. No sentiré ninguna vergüenza, ni siquiera una ligera molestia, cuando convierta un bucle de tres líneas en miles de instrucciones solo para hacerlo más rápido. No me da vergüenza hacer grandes esfuerzos de optimización o hacer los trucos más sucios. Y si no quieres que lo haga, tal vez por un día o dos, me comportaré y lo haré como quieras. Puedo transformar los métodos que estoy usando cuando quieras, sin siquiera cambiar una sola línea de tu código. Incluso puedo mostrarte cómo se vería tu código en el ensamblaje, en diferentes arquitecturas de procesador y diferentes sistemas operativos y en diferentes convenciones de ensamblaje si lo desea. Si, todo en segundos. Porque, ya sabes, puedo; y sabes, no puedes.

PD: Oh, por cierto, no estabas usando la mitad del código que escribiste. Te hice un favor y lo tiré.


99

He escrito shedloads de ensamblador para los chips 6502, Z80, 6809 y 8086. Dejé de hacerlo tan pronto como los compiladores de C estuvieron disponibles para las plataformas a las que me dirigía, e inmediatamente me volví al menos 10 veces más productivo. La mayoría de los buenos programadores usan las herramientas que usan por razones racionales.


72

Me encanta programar en lenguaje ensamblador, pero se necesita más código para hacer lo mismo que en un lenguaje de alto nivel, y hay una correlación directa entre las líneas de código y los errores. (Esto se explicó hace décadas en The Mythical Man-Month ).

Es posible pensar en C como un 'ensamblaje de alto nivel', pero obtenga algunos pasos por encima de eso y estará en un mundo diferente. En C # no lo piensas dos veces antes de escribir esto:

foreach (string s in listOfStrings) { /* do stuff */ }

Esto sería docenas, tal vez cientos de líneas de código en el ensamblaje, cada programador que lo implementa tomaría un enfoque diferente, y la siguiente persona que lo acompañaría tendría que resolverlo. Entonces, si usted cree (como muchos lo hacen) que los programas están escritos principalmente para que otras personas los lean, el ensamblaje es menos legible que el HLL típico.

Editar: acumulé una biblioteca personal de código utilizada para tareas comunes y macros para implementar estructuras de control tipo C. Pero golpeé la pared en los 90, cuando las GUI se convirtieron en la norma. Se estaba gastando demasiado tiempo en cosas que eran rutinarias.

La última tarea que tuve donde ASM era esencial fue hace unos años, escribir código para combatir el malware. Sin interfaz de usuario, por lo que fueron todas las partes divertidas sin la hinchazón.


¿Estás seguro de eso? Me parece de lectura en memoria de código completo que este no era el caso ...
jcolebrand

1
Estoy seguro de que hay un punto donde la ventaja de 'menos líneas' es superada por la desventaja de 'optimización prematura'. Pero no he visto Code Complete en años ...
egrunin

66
Es un poco irónico utilizar la "optimización prematura" como argumento para el montaje ... (aunque probablemente te malinterprete. Todavía creo que es gracioso)
Bernd Jendrissek

Todavía puede llamar a la función en ensamblador, por lo que dudo que un bucle foreach lleve decenas a cientos de líneas. ¿O qué me estoy perdiendo?
Sebastian Mach el

@phresnel: foreachhace mucho más trabajo que : crea forinstancias y utiliza un iterador de tipo específico.
egrunin el

15

Además de las respuestas de otras personas sobre legibilidad, facilidad de mantenimiento, código más corto y, por lo tanto, menos errores, y siendo mucho más fácil, agregaré una razón adicional:

velocidad del programa

Sí, en el ensamblaje puede ajustar manualmente su código para utilizar cada último ciclo y hacerlo lo más rápido posible físicamente. Sin embargo, ¿quién tiene el tiempo? Si escribe un programa C no completamente estúpido, el compilador hará un muy buen trabajo de optimización para usted. Probablemente realice al menos el 95% de las optimizaciones que haría a mano, sin tener que preocuparse por realizar un seguimiento de ninguna de ellas. Definitivamente hay una regla 90/10 aquí, donde ese último 5% de las optimizaciones terminará ocupando el 95% de su tiempo. ¿Entonces, para qué molestarse?


44
+1. Escribir código de ensamblador y escribir código de ensamblador rápido son dos cosas diferentes. Si usa un buen compilador, obtiene el código de ensamblador rápido de forma gratuita.
Niki

obtienes un código de ensamblador rápido de forma gratuita solo si sabes cómo usar el compilador, la mayoría no usa la optimización, la mayoría de las personas compilan con opciones de depuración y, como resultado, terminan con un ensamblador lento mal hecho. Sí, más del 99% del tiempo no debe tocarlo, solo toque los botones de los compiladores y no modifique la salida directamente.
old_timer

si te interesan las optimizaciones, entonces deberías hacerlo desde el compilador ... SI no te interesan las optimizaciones, pero sigues usando ensamblaje, entonces estás siendo tonto.
Brian Postow

@dwelch: Creo que puede haber algunos niños que no se molestan en averiguar cómo se usan sus herramientas. Pero dudo que personas como ellas puedan escribir código de ensamblador rápido.
Niki

13

Si un programa de producción promedio tiene 100 mil líneas de código, y cada línea tiene aproximadamente 8-12 instrucciones de ensamblador, eso sería 1 millón de instrucciones de ensamblador.

Incluso si pudiera escribir todo esto a mano a una velocidad decente (recuerde, es 8 veces más código que tiene que escribir), ¿qué sucede si desea cambiar algunas de las funciones? ¡Comprender algo que escribiste hace unas semanas de esas 1 millón de instrucciones es una pesadilla! No hay módulos, no hay clases, no hay diseño orientado a objetos, no hay marcos, no hay nada. Y la cantidad de código de aspecto similar que tiene que escribir incluso para las cosas más simples es desalentador en el mejor de los casos.

Además, no puede optimizar su código casi tan bien como un lenguaje de alto nivel. Donde C, por ejemplo, realiza una cantidad increíble de optimizaciones porque describe su intención, no solo su código, en el ensamblador solo escribe código, el ensamblador realmente no puede realizar ninguna optimización digna de nota en su código. Lo que escribes es lo que obtienes, y confía en mí, no puedes optimizar de manera confiable 1 millón de instrucciones que parches y parches a medida que lo escribes.


8

Bueno, he estado escribiendo mucho ensamblaje "en los viejos tiempos", y puedo asegurarles que soy mucho más productivo cuando escribo programas en un lenguaje de alto nivel.


8
"Asamblea es latina".
Adriano Varoli Piazza

44
@Adriano: excepto que hay muchos, muchos dialectos diferentes y no hay dos iguales.
Joachim Sauer

1
Claro, pero quise decir que aprender a programar en cualquiera de ellos te da una idea de la arquitectura de una máquina que te ayuda en niveles superiores. A menos que trate con memoria paginada, en ese caso terminará marcado. Como leer Carmen 16 de Catulo.
Adriano Varoli Piazza

55
@Adriano "La asamblea es latina", ningún asm es gruñido de hombre de las cavernas. Un gruñido para el rock 2grunts para el venado, 3grunts para el fuego: bueno para cosas simples pero difícil de manejar un imperio.
Martin Beckett

1
@ Martin: ¿Alguna vez has intentado hacer aritmética compleja con números romanos?
Adriano Varoli Piazza

6

Un nivel razonable de competencia del ensamblador es una habilidad útil, especialmente si trabaja en cualquier tipo de nivel de sistema o programación incrustada, no tanto porque tiene que escribir tanto ensamblador, sino porque a veces es importante comprender qué es el cuadro realmente haciendo . Si no tiene una comprensión de bajo nivel de los conceptos y problemas del ensamblador, esto puede ser muy difícil.

Sin embargo, en cuanto a escribir realmente mucho código en ensamblador, hay varias razones por las que no se hace mucho.

  • Simplemente no hay (casi) necesidad. Excepto por algo como la inicialización muy temprana del sistema y quizás algunos fragmentos de ensamblador ocultos en funciones o macros de C, todo el código de muy bajo nivel que alguna vez pudo haber sido escrito en ensamblador puede escribirse en C o C ++ sin dificultad.

  • El código en lenguajes de nivel superior (incluso C y C ++) condensa la funcionalidad en muchas menos líneas, y hay una considerable investigación que muestra que la cantidad de errores se correlaciona con la cantidad de líneas de código fuente. Es decir, el mismo problema, resuelto en ensamblador y C, tendrá más errores en ensamblador simplemente porque es más largo. El mismo argumento motiva el cambio a lenguajes de nivel superior como Perl, Python, etc.

  • Al escribir en ensamblador, debe lidiar con todos los aspectos del problema, desde el diseño detallado de la memoria, la selección de instrucciones, las opciones de algoritmos, la gestión de la pila, etc. Los lenguajes de nivel superior le quitan todo esto, por lo que son mucho más densos en términos de LOC.

Esencialmente, todo lo anterior está relacionado con el nivel de abstracción disponible para usted en ensamblador versus C o algún otro lenguaje. Assembler te obliga a hacer todas tus propias abstracciones, y a mantenerlas a través de tu propia autodisciplina, donde cualquier lenguaje de nivel medio como C, y especialmente los lenguajes de nivel superior, te proporcionan abstracciones fuera de la caja, así como capacidad de crear nuevos con relativa facilidad.


6

Como desarrollador que pasa la mayor parte de su tiempo en el mundo de la programación integrada, diría que el ensamblado está lejos de ser un lenguaje muerto / obsoleto. Existe un cierto nivel de codificación cercano al metal (por ejemplo, en los controladores) que a veces no se puede expresar de manera tan precisa o eficiente en un lenguaje de nivel superior. Escribimos casi todas nuestras rutinas de interfaz de hardware en ensamblador.

Dicho esto, este código de ensamblaje está envuelto de tal manera que se puede invocar desde el código C y se trata como una biblioteca. No escribimos todo el programa en conjunto por muchas razones. Primero y principal es la portabilidad; nuestra base de código se usa en varios productos que usan arquitecturas diferentes y queremos maximizar la cantidad de código que se puede compartir entre ellos. El segundo es la familiaridad del desarrollador. En pocas palabras, las escuelas no enseñan asamblea como solían hacerlo, y nuestros desarrolladores son mucho más productivos en C que en asamblea. Además, tenemos una amplia variedad de "extras" (cosas como bibliotecas, depuradores, herramientas de análisis estático, etc.) disponibles para nuestro código C que no están disponibles para el código del lenguaje ensamblador. Incluso si quisiéramos escribir un programa de ensamblaje puro, no podríamos hacerlo porque varias bibliotecas críticas de hardware solo están disponibles como C libs. En cierto sentido, es un problema de pollo / huevo. Las personas se alejan del ensamblaje porque no hay tantas bibliotecas y herramientas de desarrollo / depuración disponibles para él, pero las bibliotecas / herramientas no existen porque no hay suficientes personas que utilicen el ensamblaje para garantizar el esfuerzo que las crea.

Al final, hay un momento y un lugar para casi cualquier idioma. Las personas usan lo que les es más familiar y productivo. Probablemente siempre habrá un lugar en el repertorio de un programador para el ensamblaje, pero la mayoría de los programadores descubrirán que pueden escribir código en un lenguaje de nivel superior que sea casi tan eficiente en mucho menos tiempo.


6

Cuando escribe en conjunto, no tiene que escribir solo en códigos de instrucciones. Puede usar macros y procedimientos y sus propias convenciones para hacer varias abstracciones para hacer que los programas sean más modulares, más fáciles de mantener y más fáciles de leer.

Entonces, lo que básicamente está diciendo es que con el uso experto de un ensamblador sofisticado, puede hacer que su código ASM se acerque cada vez más a C (o de cualquier otro lenguaje de bajo nivel propio de su propia invención), hasta que finalmente sea solo tan productivo como un programador en C.

Eso responde tu pregunta? ;-)

No digo esto ociosamente: he programado usando exactamente un ensamblador y un sistema de este tipo. Aún mejor, el ensamblador podría apuntar a un procesador virtual, y un traductor separado compiló la salida del ensamblador para una plataforma de destino. Al igual que sucede con el IF de LLVM, pero en sus primeras formas data de unos 10 años. Por lo tanto, había portabilidad, además de la capacidad de escribir rutinas para un ensamblador objetivo específico donde era necesario para la eficiencia.

Escribir usando ese ensamblador fue casi tan productivo como C, y en comparación con GCC-3 (que ya existía cuando estuve involucrado) el ensamblador / traductor produjo un código que era aproximadamente igual de rápido y generalmente más pequeño. El tamaño era realmente importante, y la compañía tenía pocos programadores y estaba dispuesto a enseñar a los nuevos empleados un nuevo idioma antes de que pudieran hacer algo útil. Y teníamos el respaldo de que las personas que no conocían al ensamblador (por ejemplo, los clientes) podían escribir C y compilarlo para el mismo procesador virtual, utilizando la misma convención de llamadas, etc., de modo que se conectara perfectamente. Entonces se sintió como una victoria marginal.

Eso fue con varios años de trabajo en la bolsa desarrollando la tecnología de ensamblador, bibliotecas, etc. Es cierto que gran parte de lo que se hizo para hacerlo portátil, si solo hubiera estado apuntando a una arquitectura, entonces el ensamblador que canta y baila todo habría sido mucho más fácil.

En resumen: puede que no le guste C, pero eso no significa que el esfuerzo de usar C sea mayor que el esfuerzo de encontrar algo mejor.


5

El ensamblaje no es portátil entre diferentes microprocesadores.


Eso no es exactamente cierto con los procesadores modernos y los programas de ensamblador, puede apuntar a diferentes procesadores tal como puede hacerlo en C. Seguro que no podrá usar el conjunto completo de instrucciones en este caso, pero tampoco lo hará si lo escribe en C. La portabilidad no es la principal preocupación.
Blindy

66
Quizás te refieres a la arquitectura .
Ben S

2
@Blindy: puede apuntar a diferentes procesadores dentro de la familia x86, pero definitivamente no hay nada en común en las instrucciones de ensamblaje entre una variante x86 y un procesador ARM o un Z80 o un 8051.
semaj

Es cierto, pero tampoco puedes programar un z80 en c. Creo que todos estamos hablando de procesadores x86 / x64 normales aquí.
Blindy

1
Todo el mundo no es un x86. Nada sobre "microprocesadores diferentes" sugiere que todos ejecuten el mismo conjunto de instrucciones.
Bernd Jendrissek

5

La misma razón por la que ya no vamos al baño afuera, o por qué no hablamos latín o arameo.

La tecnología aparece y hace las cosas más fáciles y accesibles.

EDITAR: para dejar de ofender a las personas, he eliminado ciertas palabras.


44
Todavía estás ofendiendo a los luditas con la palabraTechnology
SeanJA

1
"Nosotros" no hablamos latín?
húmedo

Ni el latín ni el arameo desaparecieron porque fueron reemplazados por una mejor tecnología (es decir, un idioma más fácil de aprender / aprender). De hecho, el latín todavía está con nosotros en todas partes de Europa. Todos los idiomas romanos se basan en el latín. Hoy en día, casi medio millón de personas hablan el (neo) arameo moderno. Las razones por las que estos idiomas ya no prevalecen son históricas (geopolíticas, para ser más precisos), no tecnológicas. La misma razón por la que el inglés es la lengua franca de la ciencia y las clases dominantes de nuestra época: la gente del último imperio, los británicos (y ahora los estadounidenses) lo hablan.
el Ritz

4

¿Por qué? Sencillo.

Compara esto:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

con

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Son idénticas en cuanto a características. El segundo ni siquiera es ensamblador sino .NET IL (lenguaje intermedio, similar al código de bytes de Java). La segunda compilación transforma el IL en código nativo (es decir, casi ensamblador), lo que lo hace aún más críptico.


3

Supongo que ASM incluso en x86 (_64) tiene sentido en los casos en que gana mucho utilizando instrucciones que son difíciles de optimizar para un compilador. x264, por ejemplo, utiliza muchos asm para su codificación, y las ganancias de velocidad son enormes.


2

Estoy seguro de que hay muchas razones, pero dos razones rápidas en las que puedo pensar son

  1. El código de ensamblaje es definitivamente más difícil de leer (estoy seguro de que también lleva más tiempo escribirlo)
  2. Cuando tiene un gran equipo de desarrolladores trabajando en un producto, es útil dividir su código en bloques lógicos y protegerlo mediante interfaces.

1
Tenga en cuenta que también puede separar el ensamblaje en bloques lógicos.
Paul Williams

2

Uno de los primeros descubrimientos (lo encontrarás en Brooks ' Mythical Man-Month , que es por experiencia en la década de 1960) fue que las personas eran más o menos tan productivas en un idioma como en otro, en líneas de código depuradas por día. Obviamente, esto no es universalmente cierto, y puede romperse cuando se empuja demasiado lejos, pero generalmente fue cierto en los lenguajes de alto nivel de la época de Brooks.

Por lo tanto, la forma más rápida de obtener productividad sería usar lenguajes donde una línea de código individual hiciera más, y de hecho esto funciona, al menos para lenguajes de complejidad como FORTRAN y COBOL, o dar un ejemplo más moderno C.


2

La portabilidad siempre es un problema, si no ahora, al menos eventualmente. La industria de la programación gasta miles de millones cada año para portar software antiguo que, en el momento en que se escribió, "obviamente" no tenía ningún problema de portabilidad.


2
"No tendrá que portarse a otra arquitectura" me suena mucho a mis oídos como "No necesitará más de dos dígitos para el año".
David Thornley

¿O no podemos usar C # porque Windows podría no estar disponible el próximo año?
Martin Beckett el

Por ejemplo, las computadoras MacIntosh de Apple que se han basado en los procesadores de la serie MC68000 de Motorola, PowerPC (IBM et all) y ahora los procesadores Intel x86 (IA-32 (e)). Entonces, sí, la portabilidad es un problema para cualquier sistema utilizado durante el tiempo suficiente, y cualquier programador que no haya sido mordido por su código que dure más de lo esperado aún no tiene experiencia.
mctylr

@ Martin: Dentro de veinte años, habrá muchos programas de C # que la gente quiere ejecutar, por lo que habrá una manera de compilar y ejecutar programas de C #. No hay nada inherentemente fijo sobre C #, aunque en veinte años me sorprendería si todavía fuera tan popular como lo es ahora. Sin embargo, en veinte años nuestras CPU serán significativamente diferentes. Un programa de ensamblador escrito en 1990 bien puede ejecutarse hoy en día, pero seguramente no será óptimo y funcionará más lento que el compilado C.
David Thornley

Eso es lo que quise decir: tengo muchos más problemas de portabilidad porque un marco de alto nivel cambió desde hace 6 meses que lo que hago porque las instrucciones en un x86 cambiaron, especialmente porque el ASM codificado a mano tiende a adherirse a los métodos más simples.
Martin Beckett

2

Hubo un círculo vicioso a medida que el ensamblaje se volvía menos común: a medida que maduraban los lenguajes de nivel superior, los conjuntos de instrucciones de lenguaje ensamblador se construían menos para la conveniencia del programador y más para la conveniencia de los compiladores.

Entonces, de manera realista, puede ser muy difícil tomar las decisiones correctas sobre, por ejemplo, qué registros debe usar o qué instrucciones son un poco más eficientes. Los compiladores pueden usar la heurística para determinar qué compensaciones tienen la mejor recompensa. Probablemente podamos pensar en problemas más pequeños y encontrar optimizaciones locales que puedan vencer a nuestros compiladores ahora bastante sofisticados, pero lo más probable es que, en el caso promedio, un buen compilador haga un mejor trabajo en el primer intento que un buen programador. Eventualmente, como John Henry, podríamos vencer a la máquina, pero podríamos quemarnos seriamente para llegar allí.

Nuestros problemas ahora también son bastante diferentes. En 1986 estaba tratando de encontrar la manera de obtener un poco más de velocidad de pequeños programas que implicaban poner unos cientos de píxeles en la pantalla; Quería que la animación fuera menos desigual. Un caso justo para el lenguaje ensamblador. Ahora estoy tratando de descubrir cómo representar las abstracciones en torno al lenguaje del contrato y la política del administrador de hipotecas, y prefiero leer algo que se parezca al lenguaje que hablan los empresarios. A diferencia de las macros LISP, las macros de ensamblaje no imponen muchas reglas, por lo que, aunque pueda obtener algo razonablemente similar a un DSL en un buen ensamblador, será propenso a todo tipo de peculiaridades que ganaron ' No me causa problemas si escribí el mismo código en Ruby, Boo, Lisp, C # o incluso F #.

Sin embargo, si sus problemas son fáciles de expresar en un lenguaje ensamblador eficiente, más poder para usted.


2

Lo mismo ocurre con lo que otros han dicho.

En los viejos tiempos antes de que se inventara C, cuando los únicos lenguajes de alto nivel eran cosas como COBOL y FORTRAN, había muchas cosas que simplemente no era posible hacer sin recurrir al ensamblador. Era la única forma de obtener la flexibilidad total, poder acceder a todos los dispositivos, etc. Pero luego se inventó C, y casi todo lo que era posible en el ensamblaje era posible en C. He escrito muy poco ensamblaje desde entonces. luego.

Dicho esto, creo que es un ejercicio muy útil para que los nuevos programadores aprendan a escribir en ensamblador. No porque realmente lo usarían mucho, sino porque entonces entiendes lo que realmente está sucediendo dentro de la computadora. He visto muchos errores de programación y código ineficiente de programadores que claramente no tienen idea de lo que realmente está sucediendo con los bits y bytes y registros.


Sí, en el clavo. Fortran Disk and Tape I / O en los mainframes de IBM hace años era casi inútil, por lo que escribimos nuestras propias rutinas de E / S en 370 / Assembler y las llamamos desde el código Fortan IV. Y escribir código de ensamblaje me hizo comprender realmente la arquitectura subyacente. No he escrito ningún código de ensamblaje durante muchos años y todas las personas más jóvenes con las que trabajo nunca han escrito ninguno, pero desearía que lo hicieran, es muy educativo.
Simon Knights

2

He estado programando en ensamblaje ahora durante aproximadamente un mes. A menudo escribo un fragmento de código en C y luego lo compilo en ensamblador para ayudarme. Quizás no estoy utilizando toda la potencia de optimización del compilador de C, pero parece que mi fuente de C asm incluye operaciones innecesarias. Así que estoy empezando a ver que hablar de un buen compilador de C que supera a un buen codificador de ensamblaje no siempre es cierto.

De todos modos, mis programas de ensamblaje son muy rápidos. Y cuanto más uso el ensamblaje, menos tiempo me lleva escribir mi código porque realmente no es tan difícil. Además, el comentario sobre el montaje que tiene poca legibilidad no es cierto. Si etiqueta sus programas correctamente y hace comentarios cuando se necesita una elaboración adicional, debería estar listo. De hecho, el ensamblador es más claro para el programador porque está viendo lo que sucede a nivel del procesador. No sé acerca de otros programadores, pero para mí me gusta saber lo que está sucediendo, en lugar de que las cosas estén en una especie de caja negra.

Dicho esto, la verdadera ventaja de los compiladores es que un compilador puede comprender patrones y relaciones y luego codificarlos automáticamente en las ubicaciones apropiadas en la fuente. Un ejemplo popular son las funciones virtuales en C ++ que requieren que el compilador mapee de manera óptima los punteros de función. Sin embargo, un compilador se limita a hacer lo que el creador del compilador le permite hacer. Esto lleva a que los programadores a veces tengan que recurrir a hacer cosas extrañas con su código, agregando tiempo de codificación, cuando podrían haberse hecho trivialmente con el ensamblaje.

Personalmente, creo que el mercado es muy compatible con los idiomas de alto nivel. Si el lenguaje ensamblador fuera el único que existe en la actualidad, su programación sería aproximadamente un 70% menor de personas y quién sabe dónde estaría nuestro mundo, probablemente en los años 90. Los idiomas de nivel superior atraen a una gama más amplia de personas. Esto permite un mayor suministro de programadores para construir la infraestructura necesaria de nuestro mundo. Las naciones en desarrollo como China e India se benefician enormemente de lenguajes como Java. Estos países desarrollarán rápidamente su infraestructura de TI y las personas estarán más interconectadas. Entonces, mi punto es que los lenguajes de alto nivel son populares no porque producen un código superior sino porque ayudan a satisfacer la demanda en los mercados mundiales.


+1 para caja negra. Sí, estamos usando cajas negras, y no hay forma de mirarlas (demasiado fácil). ¿Cómo funciona realmente C # foreach ? Quién sabe. Microsoft dijo, es perfecto. Entonces debe ser.
ern0

Además, no olvides que con un 'lenguaje de alto nivel' vienen muchas otras cosas que importan en el mundo real. C viene con las bibliotecas estándar (matemáticas, procesamiento de cadenas, E / S, etc.), y luego los pesos pesados ​​como Java vienen con muchos otros paquetes y bibliotecas para conectividad, procesamiento de imágenes, procesamiento de datos, desarrollo web, etc. Es una pregunta de usar su tiempo para concentrarse en obtener 1 tarea detallada de alto rendimiento en una plataforma (por lo tanto, usando ensamblaje) en lugar de pasar el mismo tiempo ejecutando una tarea mucho más grande en múltiples plataformas con errores mínimos.
jbx

1

Ahora mismo estoy aprendiendo ensamblaje en comp org, y aunque es interesante, también es muy ineficiente para escribir. Tienes que tener muchos más detalles en tu cabeza para que las cosas funcionen, y también es más lento para escribir las mismas cosas. . Por ejemplo, un bucle simple de 6 líneas para C ++ puede ser igual a 18 líneas o más de ensamblaje.

Personalmente, es muy divertido aprender cómo funcionan las cosas a nivel de hardware, y me da una mayor apreciación de cómo funciona la informática.


1

Lo que C tiene sobre un buen ensamblador de macros es el lenguaje C. Verificación de tipos. Construcciones de bucle. Gestión automática de la pila. (Casi) gestión automática de variables. Las técnicas de memoria dinámica en ensamblador son un dolor enorme en el trasero. Hacer una lista vinculada correctamente es simplemente aterrador en comparación con C o mejor aún, lista foo.insert (). Y depuración: bueno, no hay competencia sobre qué es más fácil de depurar. Los HLL ganan manos allí abajo.

He codificado casi la mitad de mi carrera en ensamblador, lo que me hace muy fácil pensar en un ensamblador. me ayuda a ver qué está haciendo el compilador de C, lo que nuevamente me ayuda a escribir código que el compilador de C puede manejar de manera eficiente. Una rutina bien pensada escrita en C se puede escribir para generar exactamente lo que desea en ensamblador con un poco de trabajo, ¡y es portátil! Ya he tenido que reescribir algunas rutinas asm antiguas de vuelta a C por razones multiplataforma y no es divertido.

No, me quedaré con C y lidiaré con la leve desaceleración ocasional en el rendimiento frente al tiempo de productividad que gano con HLL.


1

Solo puedo responder por qué personalmente no escribo programas en ensamblado con más frecuencia, y la razón principal es que es más tedioso . Además, creo que es más fácil equivocarse sutilmente sin notarlo de inmediato. Por ejemplo, puede cambiar la forma en que usa un registro en una rutina, pero olvide cambiar esto en un solo lugar. Se ensamblará bien y es posible que no lo note hasta mucho más tarde.

Dicho esto, creo que todavía hay usos válidos para el ensamblaje. Por ejemplo, tengo varias rutinas de ensamblaje bastante optimizadas para procesar grandes cantidades de datos, usando SIMD y siguiendo el enfoque paranoico "todo es sagrado" [cita V.Stob]. (Pero tenga en cuenta que las implementaciones ingeniosas de ensamblaje a menudo son mucho peores de lo que un compilador generaría para usted).


1

C es un ensamblador de macros! ¡Y es el mejor!

Puede hacer casi todo lo que puede hacer el ensamblaje, puede ser portátil y en la mayoría de los casos excepcionales en los que no puede hacer algo, aún puede usar el código de ensamblaje incrustado. Esto deja solo una pequeña fracción de los programas que absolutamente necesita escribir en ensamblado y nada más que ensamblado.

Y las abstracciones de nivel superior y la portabilidad hacen que valga la pena para la mayoría de las personas escribir software de sistema en C. Y aunque es posible que ahora no necesite portabilidad si invierte mucho tiempo y dinero en escribir algún programa, es posible que no desee limitarse en lo que podrás usar en el futuro.


1

La gente parece olvidar que también existe la otra dirección.

¿Por qué estás escribiendo en Assembler en primer lugar? ¿Por qué no escribir el programa en un lenguaje verdaderamente de bajo nivel?

En vez de

mov eax, 0x123
add eax, 0x456
push eax
call printInt

también podrías escribir

B823010000
0556040000
50 
FF15.....

Eso tiene tantos ventajas, usted conoce el tamaño exacto de su programa, puede reutilizar el valor de las instrucciones como entrada para otras instrucciones y ni siquiera necesita un ensamblador para escribirlo, puede usar cualquier editor de texto ...

Y la razón por la que todavía prefieres Assembler sobre esto, es la razón por la que otras personas prefieren C ...


0

Porque siempre es así: el tiempo pasa y las cosas buenas también pasan :(

Pero cuando escribes código asm es una sensación totalmente diferente a cuando codificas langs de alto nivel, aunque sabes que es mucho menos productivo. Es como si fueras un pintor: eres libre de dibujar lo que quieras de la manera que quieras sin restricciones (bueno, solo por las características de la CPU) ... Por eso me encanta. Es una pena que este lenguaje desaparezca. Pero mientras alguien todavía lo recuerda y lo codifica, ¡nunca morirá!


Cierto. Por otro lado, existe la humillación que experimenta cuando el cajero y el supermercado se niegan a cobrar su cheque, diciendo desdeñosamente: "Oh, usted programa en un lenguaje de NIVEL BAJO".
Jay

0

$$$

Una empresa contrata a un desarrollador para ayudar a convertir el código en $$$. Cuanto más rápido que útil se pueda producir código , más rápido la compañía puede convertir ese código en $$$.

Los lenguajes de nivel superior son generalmente mejores para producir grandes volúmenes de código útil. Esto no quiere decir que la asamblea no tenga su lugar, ya que hay momentos y lugares donde nada más servirá.


0

La ventaja de los HLL es aún mayor cuando se compara el ensamblaje con un lenguaje de nivel superior que C, por ejemplo, Java, Python o Ruby. Por ejemplo, estos idiomas tienen recolección de basura: no hay que preocuparse por cuándo liberar una gran cantidad de memoria, y no hay fugas de memoria o errores debido a la liberación demasiado pronto.


0

Como otros mencionaron antes, la razón para que exista cualquier herramienta es qué tan eficientemente puede funcionar. Como los HLL pueden realizar los mismos trabajos que muchas líneas de código ASM, creo que es natural que el ensamblaje sea reemplazado por otros idiomas. Y para el violín cercano al hardware: hay ensamblaje en línea en C y otras variantes según el lenguaje. El Dr. Paul Carter dice en el lenguaje ensamblador de PC

"... una mejor comprensión de cómo funcionan realmente las computadoras en un nivel inferior que en lenguajes de programación como Pascal. Al obtener una comprensión más profunda de cómo funcionan las computadoras, el lector a menudo puede ser mucho más productivo desarrollando software en lenguajes de nivel superior como C y C ++. Aprender a programar en lenguaje ensamblador es una excelente manera de lograr este objetivo ".

Tenemos introducción a la asamblea en mis cursos universitarios. Ayudará a aclarar conceptos. Sin embargo, dudo que alguno de nosotros escriba el 90% del código en el ensamblado. ¿Cuán relevante es hoy el conocimiento profundo de ensamblaje?


-2

Hojeando estas respuestas, apuesto a que 9/10 de los respondedores nunca han trabajado con el ensamblaje.

Esta es una pregunta antigua que surge de vez en cuando y obtienes las mismas respuestas, en su mayoría mal informadas. Si no fuera por la portabilidad, yo mismo haría todo en ensamblaje. Incluso entonces, codifico en C casi como lo hice en ensamblador.


1
+1 menciona a personas sin experiencia en asm, y otro +1 debería "codificar en C como asm". Cuando escribo aplicaciones C ++ (sí, CPP, no C) para incrustadas, estoy codificando como si fueran asm, por ejemplo, sin usar new / malloc ().
ern0

¿Entonces usa muchas cosas como char buf [MAX_PATH] que luego se cae cuando alguien tiene datos de tamaño MAX_PATH + n? ;)
Paul

1
@paulm: ¿Te refieres a lo que hace C?
Rob

1
Espero que los autores de ensambladores no eviten el uso de malloc (). Sí, en embebido tiene limitaciones de memoria. Pero haga eso en Unix u otro escritorio (o incluso en la mayoría de los sistemas operativos móviles) y se limitará innecesariamente a usted y a sus usuarios. Además: cuanto menos LOC escriba, menos posibilidades de error, lo que significa que es probable que el código de nivel superior tenga menos errores que el inferior.
uliwitness

1
Solo busqué porque sospechaba y, sí, estoy seguro de que los redditors y HNers están aquí.
Rob
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.