¿Debo intentar hacer problemas de práctica en el ensamblaje? [cerrado]

9

Estaba mirando el problema 48 del proyecto Euler :

La serie, 1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317.

Encuentra los últimos diez dígitos de la serie, 1 1 + 2 2 + 3 3 + ... + 1000 1000 .

En Python puedo hacer esto con una sola línea:

sum((x**x for x in xrange(1,1001))

Pero el equivalente de montaje de esto sería 100 líneas y un verdadero desafío.

¿Debería hacer algunos de estos rompecabezas en ensamblaje para obtener una idea de la programación de bajo nivel y entender cómo funciona realmente la computadora?

Nishant
fuente
2
Si no sabe cómo funciona la memoria, ¿cómo se puede esperar que aborde temas como los punteros? Si no comprende cómo funciona una computadora y un sistema operativo, ¿cómo puede programar una aplicación?
Ramhound
Puedo hacer muchas abstracciones Ramhound, por eso te pregunté esto. Es posible que no entienda bien los punteros que aún pueden hacer algunas cosas en punteros como el intercambio, lo que tiene sentido lógico una vez que asume que los punteros almacenan la ubicación de la memoria de algún otro tipo de datos. temas que debo leer? ¿Sería bueno un lenguaje ensamblador y un poco de COA?
Nishant
Si no entiende bien los punteros, encontrará que es una gran desventaja en algunos lugares.
David Thornley
3
O tu línea de Python calcula x ^ 2 para x en 1..1000 (en lugar de x ^ x para x en 1..1000) o python es aún más mágico de lo que pensaba. :)
Ingo
¿Es la función "elevar al poder de" *en Python?

Respuestas:

1

Más allá del aprendizaje ensamblado, creo que aprender cómo se compila un lenguaje de bajo nivel como el C es muy valioso. Entonces mi respuesta es sí, pero de nuevo probablemente sea parcial porque disfruto de la programación de bajo nivel.

Por ejemplo, simplemente entendiendo cómo se compilan las declaraciones simples. La siguiente función,

int func(int val)
{
  int num = val * 5;
  return num;
}

... se convierte (al menos un poco interesante):

movl    %edi, -20(%rbp)
movl    -20(%rbp), %edx
movl    %edx, %eax
sall    $2, %eax
addl    %edx, %eax

Este código toma el argumento de la pila (val, el parámetro a func), lo desplaza a la izquierda 2 lugares (multiplíquelo por 2 ^ 2 o 4) y luego agrega el valor original al resultado. El resultado final es una multiplicación por 5. Un ejemplo como este ilustra una serie de cosas a tener en cuenta, como las optimizaciones del compilador. En lugar de llamar a una instrucción para multiplicar directamente por 5, cambia dos lugares para multiplicar por 4 y luego agrega el valor original. Encontré ejemplos como este para mejorar en gran medida mi comprensión de las cosas en un nivel inferior.

Genere la salida del ensamblador desde gcc con la -Sopción Sin embargo, tenga en cuenta que los resultados variarán según el compilador y el nivel de optimización.

De todos modos, no creo que ser un programador de lenguaje ensamblador sea ​​lo mismo que entender ensamblar . Nuevamente, siento que programar en un lenguaje como C y saber cómo se pone en el código de la máquina es una práctica valiosa.

Sr. Shickadance
fuente
11

Probablemente no sea necesario para poder escribir ensamblador (la mayoría de los cuales son detalles de la convención de inicialización y de llamada para su sistema).

Vale la pena entender algunos, en caso de que esté intentando depurar algo sin fuente.

PERO definitivamente vale la pena entender la máquina al menos al nivel de 'C' y punteros (esencialmente un ensamblador de alto nivel) para que sepa por qué es malo concatenar una cadena un millón de veces en un bucle.

Martin Beckett
fuente
En realidad, algunas implementaciones relativamente inteligentes no pueden hacer for i in range(1000000): s = s + '.'(t mucho) peor que las versiones "optimizadas" que estoy reutilizando s. Del mismo modo, varios otros desarrollos invalidan lo que es una suposición razonable con conocimiento de C y suponiendo una implementación ingenua. Pero en general es más útil que perjudicial. Solo tenga en cuenta que las implementaciones de lenguaje a veces son más inteligentes que usted;)
2
@delnan: solo necesitaba un breve ejemplo de dónde algo que parece inocuo en Java / C # podría ser muy costoso para el silicio. En particular, me he encontrado con muchas personas que piensan que una gran asignación de memoria y copia es instantánea.
Martin Beckett
Odio creer que delnan :-)
Nishant
5

Buena pregunta. Learning Assembly es definitivamente bueno y vale la pena el esfuerzo.

  1. Esta comprensión de bajo nivel será de gran utilidad en el desarrollo de software integrado.
  2. Refactorización a bajo nivel
  3. Le ayudará a utilizar eficazmente el depurador
  4. Le da una comprensión del código desmontado para ayudar en cosas como las cuevas de código
Aditya P
fuente
2
Tuve que buscar codecaves. Los uso mucho, pero los llamamos "desvíos" ahora. research.microsoft.com/en-us/projects/detours
ProdigySim
1

Si y no.

Si bien es cierto que le dará una mejor comprensión de lo que está haciendo su código y por qué algunas cosas son solo una mala idea, debe pensar en el esfuerzo.

El ensamblador de aprendizaje no es un proyecto de fin de semana, te llevará mucho tiempo y debes pensar si este tiempo podría o no aprovecharse mejor.

Si no te gusta el código optimizado, es probable que nunca veas beneficios iguales al esfuerzo que pones.

Skeith
fuente
1

Hice mucho ensamblador cuando era más joven y no creo que haya ayudado a entender nada fuera del ensamblador. Si echas un vistazo al ensamblador moderno, todo es material de lenguaje macro de todos modos. Por lo general, odio las analogías, pero de todos modos: ¿saber cómo funciona el motor de un automóvil lo convierte en un mejor conductor?

Ian
fuente
¿Saber cómo funciona el motor de un automóvil lo convierte en un mejor conductor? No, pero lo convierte en un mejor propietario de automóviles, porque si el motor se descompone, puede arreglarlo.
Cameron Martin
De acuerdo, pero no te hace un mejor controlador, que es la analogía que estaba usando. Al reparar el motor usted mismo, no está apoyando a la economía en general al emplear mecánicos, ... Las analogías tienen límites. En general, nunca desanimaría a alguien de buscar aprender algo si está interesado, pero creo que debe profundizar bastante en el agujero del conejo para poder aplicarlo de manera útil a los idiomas de nivel superior. Para empezar, debe comprender las optimizaciones de compilación utilizadas por el lenguaje específico si está compilado, o el intérprete o el jitter. Es un área enorme.
Ian
1

La forma en que he estado trabajando para entender el ensamblador es escribiendo programas en lenguajes de nivel superior, luego reemplazando partes con (al menos con suerte) secciones funcionalmente equivalentes de código ensamblado. Esto significa que puedo usar HLL para lo que son buenos para organizar y resolver problemas de alto nivel, y uso asm para golpear el metal.

(Cuando hablo sobre el programa host escrito en un HLL, me refiero a C u ObjC cuando intento aprender x86_64 asm, y BASIC cuando estoy trabajando en Z80, 6502 y 6809 asm).


fuente