El propósito de este texto es proporcionar una referencia para el lenguaje ensamblador de nivel universitario y los cursos de programación de sistemas. Este texto aborda el conjunto de instrucciones x86-64 para la popular clase de procesadores x86-64 que utilizan el sistema operativo Ubuntu de 64 bits. Si bien el código proporcionado y varios ejemplos deberían funcionar bajo cualquier sistema operativo de 64 bits basado en Linux, solo se han probado bajo Ubuntu 14/16/18 LTS (64 bits).
|
etiquetas: programación , ensamblador , x86-64 , desde ubuntu , pdf
Lo dice un informático
Muchas gracias!!!
No estoy en contra de su aprendizaje, siempre es importante conocer cómo funciona un procesador y lo que está haciendo tu compilador si haces cosas a bajo nivel, simplemente creo que en la mayoría de entornos (especialmente si trabajas en arm o x86) no es necesario ni recomendable su uso.
Como he dicho en otro comentario, no estoy en contra de aprender ensamblador, y es interesante saber lo que está haciendo tu compilador, pero hoy en día su uso debería reducirse a muy contadas situaciones (por supuesto IMHO).
Mejor preocúpate de escribir código limpio, que cosas como el desenrollado de bucles ya las puede hacer el compilador y si las haces a mano son feas, inmantenibles y para colmo hay que hacerlas adaptadas a cada máquina.
Si tú escribes un for (i=0; i<10; i++), el compilador no sólo es capaz de no escribir un bucle en absoluto, o de segmentarte el cuerpo del bucle en 3 fases para evitar que la instrucción de división, que es más larga, prevenga la ejecución de otras, sino que es capaz de hacerlo de forma diferente según el procesador elegido.
Hay un montón de técnicas de optimización que el compilador conoce y adapta al procesador y tú no, y además te permite mantener un código legible y mantenible.
Vete y edita un bucle segmentado y desenrollado en varias plataformas distintas.
Esto no quita para que ciertas partes muy críticas a veces ganen en ensamblador, pero no es lo habitual.
Código seguro en ensamblador, ¿estamos locos?
El compilador hacer un buen trabajo en términos generales, pero si quieres qué el código vaya a toda pastilla con el procesador que tienes a mano, del que tienes un cluster, y en el que tu empresa se ha gastado una pasta (típico caso de empresas "grandes", tipo aeronauticas, oil & gas, finanzas) en las que hay un conjunto de aplicaciones en las que un número reducido de kernels se comen el 80% del tiempo... El código va a quedar "sucio", la mayor parte de las veces porque el compilador es bueno en términos generales, pero no necesariamente en términos específicos.
El 1% restante es ese código crítico que en aplicaciones intensivas en el uso de la CPU, y tras un buen profiling, ha demostrado ser lento y consumir una buena parte de los ciclos de la CPU. Esto sólo pasa en cosas como el kérnel de un SO, compresores de vídeo, librerías matemáticas, etc, pero no en código normal y corriente.
De hecho el primer compilador de C, se compiló con B.
Y un código sucio probablemente también sea sucio en bugs difíciles de encontrar.
Que queda después de pasar el linker?
He programado un compilador de Pascal "de juguete" escrito en Python que daba como salida z80 ASM. Al final hay assembler.
Diferencia abismal había entre hacer tu propia implementación del algoritmo de Bresenham y ver luego como los maestros de la demoscene hacían lo mismo mil veces mas rápido.
Pero se me ocurren más cosas: por ejemplo, programando a alto nivel, si no sabes cómo funciona tu procesador y, sobre todo, la caché del mismo, puedes hacer cagadas tan gordas (insisto: incluso en lenguajes de alto nivel) como invalidar la caché en cada lectura a memoria sin que te des cuenta (y sin que sepas por qué).
Luego #41 también te da alguna noción más (gracias).
/cc #8