He estado programando en lenguajes de nivel superior (Python, C #, VBA, VB.NET) durante alrededor de 10 años y no entiendo completamente lo que está sucediendo, "bajo el capó".
Me pregunto cuáles son los beneficios del aprendizaje de ensamblaje y cómo me ayudará como programador. ¿Puede proporcionarme un recurso que me muestre exactamente la conexión entre lo que escribo en el código de nivel superior y lo que sucede en el ensamblaje?
for
bucle declarando variables fuera de él. ejemploRespuestas:
Porque entenderás cómo funciona realmente .
Todo se reduce a que todas las cosas que escribimos en C # o Python deben traducirse en una secuencia de acciones básicas que una computadora puede ejecutar. Es fácil pensar en una computadora en términos de clases, genéricos y listas de comprensión, pero estos solo existen en nuestros lenguajes de programación de alto nivel.
Podemos pensar en construcciones de lenguaje que se ven muy bien pero que no se traducen muy bien en una forma de hacer las cosas de bajo nivel. Al saber cómo funciona realmente, comprenderá mejor por qué las cosas funcionan de la manera en que lo hacen.
fuente
Le dará una mejor comprensión de lo que está "sucediendo bajo el capó" y cómo funcionan los punteros y el significado de las variables de registro y la arquitectura (asignación y gestión de memoria, paso de parámetros (por valor / por referencia), etc.) en general.
Para echar un vistazo rápido a C, ¿cómo es esto?
compile
gcc -S so.c
y eche un vistazo a la salida del ensamblaje enso.s
:fuente
so.c
archivo estándar para preguntas de stackoverflow (como tengoso.py
,so.awk
etc.) para probar las cosas rápidamente. So.S .. :)gcc -O -c -g -Wa,-ahl=so.s so.c
, puede ver la salida del ensamblaje para cada línea de código C. Esto hace que sea un poco más fácil entender lo que está sucediendo.5:so.c
encontrar el código de la línea 5 deso.c
.Creo que la respuesta que busca está aquí: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
Una cita del artículo:
Además, recomendaría este libro porque tiene una versión simplificada de la arquitectura de la computadora: Introducción a los sistemas de computación: de Bits y Gates a C y más allá, 2 / e Yale N. Patt, Universidad de Texas en Austin Sanjay J. Patel, Universidad de Illinois en Urbana-Champaign
fuente
En mi humilde opinión, no ayuda mucho.
Solía conocer muy bien el ensamblaje x86. Ayudó un poco cuando surgió el ensamblaje en mis cursos, surgió una vez durante una entrevista y me ayudó a demostrar que un compilador (Metrowerks) estaba generando un código incorrecto. Es fascinante cómo funciona realmente la computadora, y me siento intelectualmente más rico por haberlo aprendido. También fue muy divertido jugar en ese momento.
Sin embargo, los compiladores de hoy son mejores para generar ensamblaje que casi cualquier persona en casi cualquier pieza de código. A menos que esté escribiendo un compilador o verificando que su compilador está haciendo lo correcto, probablemente esté perdiendo su tiempo al aprenderlo.
Admito que muchas preguntas que los programadores de C ++ aún hacen útilmente se informan al conocer el ensamblaje. Por ejemplo: ¿debería usar variables de pila o montón? ¿Debo pasar por valor o por referencia constante? Sin embargo, en casi todos los casos, creo que estas elecciones deberían hacerse en función de la legibilidad del código en lugar del ahorro de tiempo computacional. (Por ejemplo, use variables de pila siempre que desee limitar una variable a un ámbito).
Mi humilde sugerencia es centrarse en las habilidades que realmente importan: diseño de software, análisis de algoritmos y resolución de problemas. Con experiencia en el desarrollo de grandes proyectos, su intuición mejorará, lo que aumenta su valor mucho más que conocer el ensamblaje (en mi opinión).
fuente
Debe estar familiarizado con un nivel 'más profundo' en el sistema en el que está trabajando. Saltar demasiado lejos de una vez no es malo, pero puede no ser tan útil como uno desearía.
Un programador en un lenguaje de alto nivel debe aprender un lenguaje de nivel inferior (C es una excelente opción). No necesita ir hasta el ensamblaje para tener una idea de lo que sucede debajo de las cubiertas cuando le dice a la computadora que cree una instancia de un objeto, o cree una tabla hash o un conjunto, pero debería poder codificar ellos.
Para un programador de Java, aprender algo de C te ayudaría con la gestión de la memoria, pasando argumentos. Escribir algo de la extensa biblioteca de Java en C ayudaría a entender cuándo usar qué implementación de Set (¿quieres un hash? O un árbol?). Tratar con char * en un entorno roscado ayudará a comprender por qué String es inmutable.
Llevado al siguiente nivel ... El programador de CA debe estar familiarizado con el ensamblaje, y los tipos de ensamblaje (que a menudo se encuentran en tiendas de sistemas integrados) probablemente harían bien en comprender las cosas a nivel de compuertas. Aquellos que trabajan con puertas deberían conocer algo de física cuántica. Y esos físicos cuánticos, bueno, todavía están tratando de descubrir cuál es la próxima abstracción.
fuente
Como no mencionó C o C ++ en la lista de lenguajes que conoce. Recomiendo encarecidamente aprenderlos bien antes de pensar en ensamblar. C o C ++ proporcionará todos los conceptos básicos que son totalmente transparentes en los lenguajes administrados y comprenderá la mayoría de los conceptos mencionados en esta página con uno de los lenguajes más importantes que podría utilizar en proyectos del mundo real. Es un verdadero valor agregado a sus habilidades de programación. Tenga en cuenta que el ensamblaje se usa en áreas muy específicas y no es tan útil como C o C ++.
Incluso iría más lejos al decir que no debes sumergirte en el ensamblaje antes de comprender cómo funcionan los idiomas no administrados. Es casi una lectura obligatoria.
Debes aprender a ensamblar si quieres ir aún más abajo. Desea saber cómo se crean exactamente todas y cada una de las construcciones del lenguaje. Es informativo pero es un nivel de complejidad muy diferente.
fuente
Si conoce bien un idioma, debe tener al menos un conocimiento básico de la tecnología un nivel de abstracción más bajo.
¿Por qué? Cuando las cosas salen mal, el conocimiento de la mecánica subyacente hace que sea mucho más fácil depurar problemas extraños y, naturalmente, escribir código más eficiente
Usando Python (/ CPython) como ejemplo, si comienza a tener bloqueos extraños o un bajo rendimiento, el conocimiento de cómo depurar el código C puede ser muy útil, al igual que el conocimiento de su método de gestión de memoria de recuento. Esto también lo ayudará a saber cuándo / si escribir algo como una extensión C, y así sucesivamente ...
Para responder a su pregunta en este caso, el conocimiento del ensamblaje realmente no ayudaría a un desarrollador experimentado de Python (son demasiados pasos en abstracción; cualquier cosa que se haga en Python daría como resultado muchas instrucciones de ensamblaje)
..pero, si tiene experiencia con C, entonces conocer "el siguiente nivel inferior" (ensamblaje) sería realmente útil.
Del mismo modo, si está utilizando CoffeScript, entonces es (muy) útil saber Javascript. Si está utilizando Clojure, el conocimiento de Java / JVM es útil.
Esta idea también funciona fuera de los lenguajes de programación: si está utilizando Assembly, es una buena idea estar familiarizado con el funcionamiento del hardware subyacente. Si es diseñador web, es una buena idea saber cómo se implementa la aplicación web. Si usted es mecánico de automóviles, es una buena idea tener algún conocimiento de física.
fuente
Escriba un pequeño programa c y desarme la salida. Eso es todo. Sin embargo, prepárese para un mayor o menor grado de código de "limpieza" que se agrega para el beneficio del Sistema Operativo.
El ensamblaje lo ayuda a comprender lo que sucede debajo del capó porque se ocupa directamente de la memoria, los registros del procesador y demás.
Si realmente desea ir al descubierto sin toda la complejidad de un sistema operativo que complica las cosas, intente programar un Arduino en lenguaje ensamblador.
fuente
No hay una respuesta definitiva, ya que los programadores no son todos de un tipo. ¿NECESITA saber qué hay debajo? Si es así, entonces aprende. ¿solo quieres aprenderlo por curiosidad? Si es así, entonces aprende. Si no tendrá ningún beneficio práctico para usted, ¿por qué molestarse? ¿Se necesita el nivel de conocimiento de un mecánico solo para conducir un automóvil? ¿Necesita un mecánico el nivel de conocimiento de un ingeniero, solo para trabajar en un automóvil? Esta es una analogía seria. Un mecánico puede ser un mecánico muy bueno y productivo sin bucear para comprender en profundidad los vehículos que mantiene. Lo mismo para la música. ¿De verdad sondear las complejidades de la melodía, la armonía y el ritmo para ser un buen cantante o jugador? No. Algunos músicos excepcionalmente talentosos no pueden leer un montón de partituras, y mucho menos decirte la diferencia entre los modos Dorian y Lydian. Si quieres, bien, pero no, no es necesario. Si usted es un desarrollador web, el ensamblaje no tiene un uso práctico que se me ocurra. Si está en sistemas embebidos o algo realmente especial, entonces podría ser necesario, pero si lo fuera, lo sabría.
Aquí está la opinión de Joel sobre este valor de aprender un lenguaje de nivel no alto: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
fuente
En realidad, lo que probablemente sería mejor para usted sería una clase que no existe (que yo sepa) en ninguna parte: sería una clase que combine una breve descripción del lenguaje de máquina / ensamblador y conceptos de direccionamiento de almacenamiento con un recorrido por la construcción del compilador , generación de código y entornos de tiempo de ejecución.
El problema es que con un lenguaje de alto nivel y muy alejado del hardware como C # o Python, realmente no aprecias el hecho de que cada movimiento que haces se convierte en cientos, si no miles, de instrucciones de máquina, y no lo haces Tienden a comprender cómo unas pocas líneas de un lenguaje de alto nivel pueden causar que se acceda y modifique grandes cantidades de almacenamiento. No es tanto que necesite saber con precisión lo que está sucediendo "debajo de las sábanas", sino que debe tener una apreciación del alcance de lo que está sucediendo y una concepción general de los tipos de cosas que ocurren.
fuente
Mi respuesta a esta pregunta ha evolucionado relativamente recientemente. Las respuestas existentes cubren lo que hubiera dicho en el pasado. En realidad, esto aún está cubierto por la respuesta principal : el punto "apreciar las construcciones en la programación de alto nivel", pero es un caso especial que creo que vale la pena mencionar ...
Según esta publicación del blog de Jeff Atwood , que hace referencia a un estudio, comprender la asignación es un tema clave para comprender la programación. Los programadores principiantes entienden que la notación solo representa los pasos que sigue la computadora y razona por los pasos, o bien se confunde perpetuamente por analogías engañosas con ecuaciones matemáticas, etc.
Bueno, si entiendes lo siguiente del ensamblador 6502 ...
Eso realmente son solo los pasos. Luego, cuando aprenda a traducir eso a una declaración de asignación ...
No necesita una analogía engañosa con una ecuación matemática: ya tiene un modelo mental correcto para mapearla.
EDITAR : por supuesto, si la explicación que obtienes
LDA variable
es básicamenteACCUMULATOR = variable
, que es exactamente lo que obtienes de algunos tutoriales y referencias, terminas donde comenzaste y no es de ninguna ayuda.Aprendí 6502 ensamblador como mi segundo idioma, el primero era Commodore Basic, y realmente no había aprendido mucho de eso en ese momento, en parte porque había muy poco que aprender, pero también porque el ensamblador parecía mucho más interesante en ese entonces. . En parte las veces, en parte porque yo era un geek de 14 años.
No recomiendo hacer lo que hice, pero me pregunto si estudiar algunos ejemplos muy simples en un lenguaje ensamblador muy simple podría ser un preliminar valioso para aprender idiomas de alto nivel.
fuente
A menos que sea un escritor compilador, o necesite algo altamente optimizado (como el algoritmo de procesamiento de datos), la codificación de ensamblaje de aprendizaje no le proporcionará ningún beneficio.
Escribir y mantener el código escrito en ensamblador es muy difícil, por lo tanto, incluso si conoce muy bien el lenguaje ensamblador, no debe usarlo, a menos que no haya otras formas.
El artículo " Optimización para SSE: un estudio de caso " muestra lo que es posible hacer si va al ensamblaje. El autor logró optimizar el algoritmo de 100 ciclos / vector a 17 ciclos / vector.
fuente
Escribir en conjunto no le daría un aumento mágico de la velocidad, ya que debido a la cantidad de detalles (asignación de registros, etc.) probablemente escribirá el algoritmo más trivial de la historia.
Además, con los procesadores modernos (leídos - diseñados después de los años 70-80), el ensamblaje no le proporcionará una cantidad suficiente de detalles para saber qué está sucediendo (es decir, en la mayoría de los procesadores). Las PU modernas (CPU y GPU) son bastante complejas en lo que respecta a las instrucciones de programación. Conocer los conceptos básicos de ensamblaje (o seudoensamblaje) permitirá comprender los libros / cursos de arquitectura de computadoras que proporcionarían más conocimientos (cachés, ejecución fuera de orden, MMU, etc.). Por lo general, no necesita conocer ISA complejo para comprenderlos (MIPS 5 es un IIRC bastante popular).
¿Por qué entender procesador? Podría darte mucha más comprensión de lo que está sucediendo. Digamos que escribes multiplicación matricial de manera ingenua:
Puede ser 'lo suficientemente bueno' para su propósito (si es una matriz 4x4, podría compilarse de todas formas con instrucciones vectoriales). Sin embargo, hay programas bastante importantes cuando compila matrices masivas: ¿cómo optimizarlas? Si escribe el código en ensamblado, podría tener un pequeño porcentaje de mejora (a menos que haga lo que la mayoría de la gente hace, también de manera ingenua, subutilizando registros, cargando / almacenando en la memoria constantemente y, de hecho, teniendo un programa más lento que en lenguaje HL) .
Sin embargo, puede revertir las líneas y ganar rendimiento mágicamente (¿por qué? Lo dejo como 'tarea'): IIRC, dependiendo de varios factores para matrices grandes, puede ser incluso 10x.
Dicho esto, se está trabajando en que los compiladores puedan hacerlo ( grafito para gcc y Polly para cualquier cosa que use LLVM). Incluso son capaces de transformarlo en (lo siento, estoy escribiendo bloqueo de memoria):
Para resumir: conocer los conceptos básicos de un ensamblaje le permite profundizar en varios 'detalles' del diseño del procesador que le permitiría escribir programas más rápidos. Puede ser bueno saber las diferencias entre las arquitecturas RISC / CISC o VLIW / procesador vectorial / SIMD / ... Sin embargo, no comenzaría con x86, ya que tienden a ser bastante complicados (posiblemente ARM también): saber lo que es un registro, etc. es IMHO suficiente para comenzar.
fuente
Normalmente es MUY importante para propósitos de depuración. ¿Qué haces cuando el sistema se rompe en medio de una instrucción y el error no tiene sentido? Es mucho menos un problema con los lenguajes .NET siempre que solo use un código seguro; el sistema casi siempre lo protegerá de lo que sucede debajo del capó.
fuente
En resumen, creo que la respuesta es porque puedes hacer más si aprendes ensamblaje. El ensamblaje de aprendizaje otorga acceso a los ámbitos de la programación de dispositivos integrados, la penetración y la elusión de la seguridad, la ingeniería inversa y la programación de sistemas en los que es muy difícil trabajar si no conoce al ensamblador.
En cuanto a aprender a mejorar el rendimiento del programa, esto es dudoso en la programación de aplicaciones. La mayoría de las veces hay muchas cosas en las que enfocarse antes de alcanzar este nivel de optimización, como optimizar su acceso de E / S tanto en el disco como en la red, optimizar la forma en que construye la GUI, elegir los algoritmos correctos y maximizar todos sus núcleos , ejecutando el mejor hardware que el dinero puede comprar y cambiando de los idiomas interpretados a los compilados. A menos que esté creando software para otros usuarios finales, el hardware es barato en comparación con el salario por hora de un programador, especialmente con la disponibilidad en la nube.
Además, debe sopesar la mayor velocidad de ejecución del programa con la legibilidad de su código después de ser atropellado por un autobús, salir o volver a la base de código para cambiarlo un año después de que escribió la última versión.
fuente
Recomendaría algoritmos de aprendizaje: clasificación, listas vinculadas, árboles binarios, hashing, etc.
También aprenda lisp, vea Estructura e interpretación de programas de computadora groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures Este video curso le enseñará todo lo que necesita saber, incluidos los algoritmos (cómo hacer todo en función de algunos comandos primitivos, un primitivo lisp y algunos provocadores de ensamblador).
Finalmente, si debe aprender ensamblador, aprenda uno fácil como ARM (también se usa en aproximadamente 4 veces más dispositivos que x86).
fuente
Bueno, la respuesta es que simplemente porque el lenguaje que está utilizando debe interpretarse o compilarse en ensamblador al final. No importa el idioma o la máquina.
El diseño de los idiomas se deriva de la forma en que funciona la CPU. Más sobre programas de bajo nivel, menos sobre programas de alto nivel.
Terminaré diciendo que no solo es necesario conocer un ensamblador pequeño sino también la arquitectura de la CPU, que se aprende aprendiendo ensamblador.
Algunos ejemplos: hay muchos programadores de Java que no entienden por qué esto no funciona, e incluso menos que saben lo que sucede cuando lo ejecutas.
Si conociera a un pequeño ensamblador, siempre sabría que no es lo mismo el contenido de una ubicación de memoria frente al número en la variable de puntero que "apunta" a esa ubicación.
Peor aún, incluso en los libros publicados leerá algo como en JAVA, las primitivas se pasan por valor y los objetos por referencia, lo cual es completamente incorrecto. Todos los argumentos en Java se pasan por valor, y Java NO puede pasar objetos a funciones, solo punteros, que se pasan por valor.
Si ahora ensamblas es obvio lo que está sucediendo, si no es así, es tan complicado explicar que la mayoría de los autores simplemente te dicen una mentira piadosa.
Por supuesto, las ramificaciones de estos son sutiles pero pueden meterte en problemas reales más adelante. Si sabe que el ensamblador no es un problema, si no, se encontrará con una larga y larga noche de depuración.
fuente
String a = "X"; String b = "X"; if( a==b) return true;
lo que de hecho se== true
debe a algo llamadoString interning
que hace el compilador. Todas las otras declaraciones de Java también están equivocadas. Java no tiene punteros, tiene referencias que no son lo mismo. Y nada de eso tiene nada que ver con el ensamblador de ninguna manera. Java pasa primitivas por valor, así como referencias por valor. Java no tiene punteros, por lo que no puede pasarlos por nada. De nuevo, todo es irrelevante para conocer ASM.