¿Cómo el aprendizaje ayuda a ensamblar en la programación? [cerrado]

132

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?

Yuck
fuente
2
Si realmente quiere saber qué hay debajo de su código, consulte el manual del procesador Intel (solo la parte introductoria): download.intel.com/products/processor/manual/325462.pdf . Tal vez esto sea un poco más profundo de lo que querías, pero me parece útil.
superM
44
Si desea saber qué sucede debajo del capó específicamente en .Net, es posible que desee obtener más información sobre CIL. Es similar al ensamblaje en algunos aspectos, pero mucho más alto nivel. Debido a eso, es más fácil de entender que el ensamblaje real.
svick
66
Si aprende el ensamblaje, puede evitar pensar que está optimizando un forbucle declarando variables fuera de él. ejemplo
StriplingWarrior
77
Oh Dios mío. Me acabas de recordar sobre la clase de idiomas de la Asamblea que tomé en la universidad hace aproximadamente 1 año. Es sorprendente ver cómo las cosas extremadamente simples que damos por sentado se traducen en cientos o incluso miles de operaciones más pequeñas y de bajo nivel. Las computadoras son máquinas extraordinarias.
Radu Murzea
14
El ensamblaje de aprendizaje le otorgará un amor profundo y permanente por el concepto de lenguaje de programación que lo protege de NUNCA tener que volver a escribir código complejo en el ensamblaje.
Shadur

Respuestas:

188

Porque entenderás cómo funciona realmente .

  • Comprenderá que las llamadas a funciones no son gratuitas y por qué la pila de llamadas puede desbordarse (por ejemplo, en funciones recursivas). Comprenderá cómo se pasan los argumentos a los parámetros de la función y las formas en que se puede hacer (copiando memoria, señalando a la memoria).
  • Comprenderá que la memoria no es gratuita y lo valiosa que es la administración automática de memoria. La memoria no es algo que "solo tiene", en realidad necesita ser administrado, cuidado y lo más importante, no olvidado (porque necesita liberarlo usted mismo).
  • Comprenderá cómo funciona el flujo de control en el nivel más fundamental.
  • Apreciará más las construcciones en lenguajes de programación de nivel superior.

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.

Simeon Visser
fuente
12
+1 para "Apreciará más las construcciones en los lenguajes de programación de nivel superior" solo. Gran respuesta.
DevSolo
42
Excepto que después de unas semanas de asm, comenzarás a pensar en C como un lenguaje de programación de alto nivel. A menos que esté hablando con desarrolladores de dispositivos integrados de bajo nivel, decir eso en voz alta hará que la mayoría de la gente piense que está un poco loco.
Dan Neely
19
@Dan: Es curioso cómo cambian estos términos con el tiempo. Hace 20 años, cuando comencé a programar, si le hubieras preguntado a alguien que diría "¡Por supuesto que C es un lenguaje de alto nivel!" Eso debería ser obvio; Proporciona un modelo estandarizado de acceso a memoria y almacenamiento dinámico. Y eso es una abstracción seria lejos del hardware; en un lenguaje de bajo nivel, debe realizar un seguimiento de todas las direcciones de memoria, o si está haciendo algo realmente elegante, ¡debe escribir su propio asignador de montón! Así que tengo que preguntarme, ¿cuál es el criterio que hace que algo sea de alto o bajo nivel hoy?
Mason Wheeler
99
Alto nivel / bajo nivel no es un binario. Un programador completo que haya escrito tanto ensamblaje como Python en su carrera podría considerar C o C ++ un lenguaje de nivel medio.
Russell Borogove
66
Esas son cosas importantes para entender, pero se cubren fácilmente en un nivel abstracto: por ejemplo, en un curso introductorio en computadoras en el nivel de instrucción de máquina. No soy un programador de ensamblaje, pero los entiendo bien, si lo digo yo mismo. En algunas respuestas SO veo discusión sobre cachés de instrucciones y tuberías, y esas realmente hacen que mi cabeza gire; pero este nivel de subinstrucción falta (hasta ahora) en las respuestas. Entonces, ¿cuál es el beneficio de aprender realmente la programación de ensamblaje, en lugar de tomar un curso básico?
alexis
33

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?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

compile gcc -S so.cy eche un vistazo a la salida del ensamblaje en so.s:

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits
Levon
fuente
2
+1: ¡Buen consejo! Puedes aprender mucho mirando lo que hace el compilador de C.
Giorgio
8
... ¿Fue el SOS intencional? (pide ayuda, etc.)
Izkata
1
@ Izkata, ja, ja ... bueno, ni siquiera me di cuenta de eso. Tengo un so.carchivo estándar para preguntas de stackoverflow (como tengo so.py, so.awketc.) para probar las cosas rápidamente. So.S .. :)
Levon
99
Si compila con 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.
Mackie Messer
1
Sí, la salida es larga. Puede buscar para 5:so.cencontrar el código de la línea 5 de so.c.
Mackie Messer
30

Creo que la respuesta que busca está aquí: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language

Una cita del artículo:

Si bien es cierto, probablemente no te encuentres escribiendo la aplicación de tu próximo cliente en conjunto, todavía hay mucho que ganar aprendiendo el ensamblaje. Hoy en día, el lenguaje ensamblador se usa principalmente para la manipulación directa del hardware, el acceso a instrucciones especializadas del procesador o para abordar problemas críticos de rendimiento. Los usos típicos son controladores de dispositivos, sistemas integrados de bajo nivel y sistemas en tiempo real.

El hecho es que, cuanto más complejos se vuelven los lenguajes de alto nivel, y cuanto más ADT (tipos de datos abstractos) se escriben, se incurre en más gastos generales para admitir estas opciones. En los casos de .NET, quizás MSIL hinchado. Imagina si supieras MSIL. Aquí es donde brilla el lenguaje ensamblador.

El lenguaje ensamblador es lo más cercano al procesador que puede obtener como programador, por lo que un algoritmo bien diseñado es excelente: el ensamblaje es ideal para la optimización de la velocidad. Se trata de rendimiento y eficiencia. El lenguaje ensamblador le brinda un control completo sobre los recursos del sistema. Al igual que una línea de ensamblaje, usted escribe código para insertar valores individuales en registros, maneja direcciones de memoria directamente para recuperar valores o punteros.

Escribir en conjunto es comprender exactamente cómo el procesador y la memoria trabajan juntos para "hacer que las cosas sucedan". Tenga en cuenta que el lenguaje ensamblador es críptico y el tamaño del código fuente de las aplicaciones es mucho más grande que el de un lenguaje de alto nivel. Pero no se equivoque al respecto, si está dispuesto a dedicar el tiempo y el esfuerzo para dominar la asamblea, mejorará y se convertirá en un destacado en el campo.

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

notkilroy
fuente
77
Esto describe para qué se usa ASM y menciona que los HLL están hinchados, pero el único beneficio específico dado para aprender ASM es escribir código súper rápido. Sí, pero incluso si aprende ASM, ¿qué posibilidades tiene de incorporarlo realmente en las aplicaciones? Suponiendo que escriba aplicaciones empresariales, no controladores de hardware o controladores de dispositivos.
+1 @notkilroy, gracias por el enlace y especialmente por la recomendación del libro
Anthony
2
@ Jon, realmente no entiendo por qué lo harías si estás desarrollando software empresarial. Una cosa es si eres un DBA, o escribes un compilador, o tienes un espacio de memoria limitado, pero no creo que mucha gente lo toque con frecuencia. El compilador se encarga principalmente de la optimización, que es la razón más importante para escribir en ensamblador. A veces ayuda al rastrear pérdidas de memoria.
Brynne
Como me especializo en el desarrollo de aplicaciones comerciales, confío principalmente en las herramientas de desarrollo de aplicaciones basadas en SQL que usan un 4GL. Me permiten crear rápidamente un prototipo de una aplicación y personalizarla en un sistema de producción. Raramente necesito escribir un cfunc invocable. ¡El tiempo de entrega y el tiempo de modificación son factores importantes en mi mundo!
Frank R.
2
Estoy bastante en desacuerdo. Un optimizador automatizado a menudo puede vencer a un programador humano para crear un ensamblaje rápido.
DeadMG
22

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).

Neil G
fuente
2
No estoy de acuerdo Si tiene un amplio conocimiento sobre un cierto algoritmo y una buena comprensión del hardware, generalmente es posible crear un código de ensamblaje que esté mejor optimizado que lo que el compilador puede crear, ya que tiene que ser seguro. Saber aproximadamente cómo se traduce su código en ensamblado también ayuda al hacer optimizaciones.
Leo
La optimización no es la razón para aprenderla. En ese aspecto, estoy de acuerdo con Neil G. Sin embargo, a Neil G le falta el punto; Está infravalorando cómo su comprensión subyacente de la máquina real informa cómo utiliza el lenguaje de alto nivel.
Warren P
En mi experiencia, un algoritmo se hace rápido al implementarlo, medir cosas, encontrar formas de optimizarlo, implementar una mejor manera, etc., etc. El problema con el ensamblaje es que lleva mucho tiempo implementarlo, por lo que no Tener la oportunidad de refinamiento repetido.
gnasher729
Hay muy pocos casos para codificar en el ensamblaje en estos días, pero saber cómo funciona es simplemente invaluable y ayudará mucho a aquellos que quieran saber cómo funciona todo. Por ejemplo, me resulta difícil seguir las cosas cuando no sé por qué está sucediendo.
Winger Sendon
21

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.

usuario40980
fuente
1
Un nivel más profundo es lo correcto. Tiendo a ir por un par, pero asumir que el conocimiento de ensamblaje x86 vale la inversión en comparación con estudiar MSIL para un programador de C # es pedir demasiado. Como alguien que estudió ensamblaje y física de estado sólido en la universidad, no creo que conocer la física del diseño de puertas me haya ayudado en absoluto, además de graduarme con un título en electrónica.
Muhammad Alkarouri
@MuhammadAlkarouri Estaba pensando en entender las fugas actuales, la duración de las carreras, la resistencia y el impacto del calor en el sistema. La comprensión del "por qué" subyacente ayuda a tomar decisiones más que las reglas de separación mínima de trazas y tolerancias operativas.
5

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.

AhHatem
fuente
5

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.

dbr
fuente
3

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.

Robert Harvey
fuente
3

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

GrayFox374
fuente
2

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.

Daniel R Hicks
fuente
1

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 ...

LDA variable
CLC
ADC #1
STA variable

Eso realmente son solo los pasos. Luego, cuando aprenda a traducir eso a una declaración de asignación ...

variable = variable + 1;

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 variablees básicamente ACCUMULATOR = 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.

Steve314
fuente
0

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.

BЈовић
fuente
1
El autor no usó ninguna instrucción vectorial o intrínseca en la versión C ++. No necesita ensamblador para escribir código SSE.
gnasher729
@ gnasher729 Sí, no necesitas. Pero con el ensamblaje, el programa puede ejecutarse mucho más rápido. Un humano puede ser más inteligente que el compilador después de todo (en casos raros).
Bћовић
0

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:

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

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.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

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):

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

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.

Maciej Piechotka
fuente
Me parece interesante que haya proporcionado varios ejemplos de código, pero ninguno de ellos está en lenguaje ensamblador.
Robert Harvey
-1

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ó.

Loren Pechtel
fuente
-2

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.

Peter Smith
fuente
-3

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).

ctrl-alt-delor
fuente
-8

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.

String a = "X";
String b = "X";
if(a==b)  
    return true;

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.

Alex Vaz
fuente
55
Su primer párrafo es completamente incorrecto: los idiomas no se compilan en ASM, se compilan en Código máquina. Los intérpretes tampoco compilan en ASM, interpretan el código o el código de bytes y llaman a funciones o métodos en el código de máquina precompilado.
66
Cualquier cosa que reclames sobre Java también es incorrecta. Comenzando con String a = "X"; String b = "X"; if( a==b) return true;lo que de hecho se == truedebe a algo llamado String interningque 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.
Siempre pensé que los lenguajes de nivel superior se compilaban en objetos (código de máquina) o pseudocódigo, y no en ASM.
Frank R.
@FrankComputer correcto, pero los bytes del código de máquina se asignan más o menos 1: 1 a las instrucciones de ensamblaje, por lo que puede traducir fácilmente entre un objeto de código y ASM (descompilación o ensamblaje)
dbr
2
@FrankComputer la última vez que miré gcc compiló C / C ++ / fortran / java / ada / etc al código de byte interno, y el código de byte interno al ensamblador. Luego envía este código de ensamblador a un ensamblador para convertirlo en código de máquina.
ctrl-alt-delor