• Compra una licencia de Windows 10/11 (10€) u Office (18€) al mejor precio u Office al mejor precio. Entra en este post con las ofertas
  • Conoce los Días Naranjas de PcComponentes: descuentos de hasta un 40% en tecnología. Entra en este post con las ofertas
  • ¡Bienvenid@! Recuerda que para comentar en el foro de El Chapuzas Informático necesitas registrar tu cuenta, tardarás menos de 2 minutos y te dará valiosa información además de ayudarte en lo que necesites o pasar un rato agradable con nosotros.

Programación en ensamblador

Registrado
5 May 2020
Mensajes
30
Puntos
8
En la universidad nos han enseñado a programar un microcontrolador (PIC18F4321) y para encontrar sus características (instrucciones, registros, timers, watch-dog...) es tan fácil como buscar "<microcontrolador> datasheet" en Google. Mi problema es que me gustaría programar algo para un ordenador (sí, un salto importante de arquitectura de 8~16 bits a una de 64) y no se donde encontrar la información.

La arquitectura de mi PC es de 64 bits y mi CPU (si afecta en algo) AMD 3950X. ¿Alguien podría indicarme como puedo hacerlo para conseguir la información equivalente a un microcontrolador?

Gracias.
 
Ten en cuenta que un PIC es un pequeñin que creo recordar sólo tiene 35 instrucciones, y los lenguajes de programación son prácticamente a bajo nivel. En PC algo similar, por comparar, pregunta a la Wikipedia o a Google por 'ensamblador x86-x64', pero creo que usar un lenguajde de programación de alto nivel es harto recomendable.
 
Ten en cuenta que un PIC es un pequeñin que creo recordar sólo tiene 35 instrucciones, y los lenguajes de programación son prácticamente a bajo nivel. En PC algo similar, por comparar, pregunta a la Wikipedia o a Google por 'ensamblador x86-x64', pero creo que usar un lenguajde de programación de alto nivel es harto recomendable.
Hola,

Mi idea era programar en C y ensamblador, aprovechando los pequeños detalles que ofrece (por ejemplo, en un sitio leí que la ALU podia realizar 4 operaciones del mismo tipo al mismo tiempo, y eso es algo que solo puedes aprovechar en ensamblador).
 
Seguramente probando con las búsquedas similares a: "programming for a microcontroller"? Te disparo una nube de ideas, haber si sale algo que pueda ser de provecho.. Aunque no prometo ningún milagro.

---

No sé. Si exactamente ¿Assambly sería para esto? Creo que sí, pero no estoy 100% seguro.
MMMM.. tu mismo dices, ¿Lenguaje ensamblador? ¿Libro de Lenguaje Ensamblador? ¿Lenguaje de bajo nivel? Introduction to x64 Assembly, x86-64 Assembly Language Programming with Ubuntu, ¿De dónde aprender a ensamblar x64? [cerrado], x86 Assembly, 64 bit - aaron bloomfield @ github.io, Writing 64-bit programs, 64-Bit-NASM-Assembly-Code-Examples, X86 Assembly/16, 32, and 64 Bits, Hola mundo para Linux x86_64 (Intel 64 bit) Extraído de la búsqueda -> Assembly language for 64 bits

No sé. Si por esa línea..
 
La arquitectura de mi PC es de 64 bits y mi CPU (si afecta en algo) AMD 3950X. ¿Alguien podría indicarme como puedo hacerlo para conseguir la información equivalente a un microcontrolador?

Te interesa el ensamblador x86 (arquitectura x86 64 bit). Aquí tienes información de la propia AMD sobre los registros de sus procesadores: Developer Guides, Manuals & ISA Documents - AMD Ten en cuenta que también existen más juegos de instrucciones y registros específicos que no están en el x86, como SSE o AVX, y que tu procesador también incorpora.

Dicho eso, yo no te recomiendo invertir demasiado en ensamblador en procesadores x86 salvo que sepas al 100% dónde quieres meterte. Con eso no me refiero que sepas o no ensamblador, sino que tengas echado el ojo a algún uso realista y accesible (empleo principalmente) para el ensamblador x86. Si no es el caso (y me atrevo a apostar por que no lo es), no te recomiendo entrar muy fuerte en el mundo del ensamblador x86.

En su día aprendí ensamblador e hice algunas cosas más por aprender y tener cultura general que otra cosa. Nunca me ha hecho falta, y creo que en toda mi vida profesional no he visto ni una sola oferta de empleo donde se exigiera ensamblador x86. En cambio, para microcontroladores sí que va bien y es un nicho mucho más amplio que el de x86.

Una buena práctica en tu situación sería escribir algún código en C que consistiera en algo más que hacer un par de sumas y que escribieras un código que hiciera lo mismo en ensamblador, para después comparar el rendimiento de ambas versiones así como examinar qué ensamblador ha generado el compilador de C. Te darás cuenta de que el compilador está optimizando el código mucho más agresivamente que tú y que está haciendo algunas cosas que a ti no se te ocurriría hacer nunca, dando como resultado que tu ensamblador, en principio muy optimizado, rinde peor que tu código en C.

En resumen, creo que está bien conocerlo, pero sabiendo que su uso real en ordenadores es MUY nicho. Algunos ejemplos: Why do you program in assembly? (aunque el link tiene ya una edad).

El panorama es totalmente distinto en PC que en los microcontroladores. En este caso la recomendación si quieres bajo nivel es C, C++, Rust y Go, y ensamblador sólo de forma muy puntual. No obstante como cultura general los enlaces que hemos visto hasta ahora tienen mucha info y creo que sí que viene bien leerlos para saber qué hay bajo el capó en la CPU.
 
Aquí tienes información de la propia AMD sobre los registros de sus procesadores: Developer Guides, Manuals & ISA Documents - AMD
Justo eso era lo que pedía, muchísimas gracias.

Respecto a lo que me has dicho, soy consciente que C hace muy buen trabajo (se de gente que sabe assembler, y después de ver el código generado por C ven que no merece la pena trabajar con él). Pero mi idea no era hacer algo super complejo (que seria tedioso y muy mal optimizado), si no algo pequeño y concreto, aprovechando las ventajas que ofrece mi CPU y que otra no ofrecería.

Gracias de nuevo,
Roger.
 
Me alegro de que te sirvan esos recursos. Esto que has comentado ahora a mi me parece perfecto. Hay un caso de uso que viene al pelo a lo que estamos hablando. Me encantan estas historias :D

Sucedió cuando id Software portó el Doom a la Super Nintendo. En general lo escribieron entero en C, pero tuvieron que escribir una parte muy pequeña en ensamblador para que la SNES pudiera mover el juego: el renderer de tiles. Es la parte que dibuja en pantalla los sprites de techo, suelo y paredes en perspectiva para que parezca 3D, y que el compilador en C no hacía lo suficientemente rápido como para que el juego fuera fluido.


De id Software hay alguna otra historieta de este tipo. Ya la comentaremos por el foro cuando salga el tema.
 
lo q recuerdo cuando pienso en ensamblador son los cronogramas de ejecucion q haciamos en primero de carrera xD
si quieres darle al ensamblador adelante, lo unico q para hacer cualquier cosa son decenas de lineas de codigo dnd hay cientos de sitios dnd meter la pata .. prefiero escalar una montaña descalzo ^_^
lo bueno es q luego meterte a crackear cosas sera un paseo x'D
 
Assembler y Assembly son dos cosas muy distintas.
El Assembler es código 1:1 que la cpu entiende directamente. Es decir, en un lenguaje
1. de alto nivel, 1 instrucción equivale a varias en Assembler
2. 1 instrucción Assembler es 1 acción en la cpu

Es cierto, por lo general, que un buen compilador C genera muy buen código en Assembler.
Es cierto, que un muy buen programa en Assembler es muchísimo mejor que el mejor compilador en C.
Lo anterior pareciera un contrasentido pero no lo es.
En los lenguajes, en general, el código pierde mucho tiempo verificando características de las variables. Es decir y poniendo un ejemplo, si la variable es int entonces debe verificar que los valores estén en el rango; en Assembler no es necesario verificar el rango dado que ya en el diseño está definido por el la cantidad de bits. Entonces, en Assembler no es necesario verificar el overflow (por mencionar una característica).
En Assembler se pueden ejecutar varias instrucciones en paralelo y en distintos registros al mismo tiempo en 1 clock, lo parte negativa es que hay que saber muy bien el tipo de instrucción y que recursos de la cpu utiliza, lo cual es muy desgastante y se requieren muchas horas de trabajo.
Bien. El gran mito que existe entre 32bits y 64bits, es que basta con compilar a 64bits y se gana rendimiento. No es tan así porque una aplicación 32bits al compilarla a 64bits, no mejora el uso de recursos en la cpu sino que cambia los códigos de las instrucciones.
Lo que no es mito, es que en Assembler de 64bits el aumento de rendimiento es impresionante, PERO requiere saber muy bien las instrucciones y los recursos utilizados en la cpu.
Ok. Por ejemplo, en 32 bits hay una determinada cantidad de registros (EAX, EBX, etc) y no todos se pueden utilizar a la misma vez y de manera libre; en 64 bits se tienen 16 registros que se pueden utilizar de manera libre (contadas excepciones existen) y concurrentemente en la cpu y en 1 clock o en la misma cantidad de clock.

Para no profundizar mas, daré un ejemplo de porqué un muy buen compilar no puede igualar el rendimiento de un muy buen programa Assembler.
Tenemos un programa en C (no en c++ porque es muy pesado del punto de vista estructuras y uso de recursos para el compilador). Esta programa calcula operaciones matemáticas sobre números en un rango de 2^128 y el resultado está dentro del rango de 2^256 sin perder ningún dígito ni redondeo alguno. Este último punto implica que no se ocupa un formato de 64bits y algunos se ocupan para la mantisa y otros para los digitos del resultado, sino que están todos los dígitos.
Este programa en C de alto rendimiento y compilado en CBuilder demoraba al multiplicar 2 números 2^128 muchas horas. Se hizo el análisis del algoritmo y se identifico la parte que hacía la fuerza bruta y se codificó en Assembler de 32bits (en su momento). El tiempo, si mal no recuerdo, bajo a menos de 2 minutos, la cpu subió varios grados y se verificó el resultado con un juego de números que se obtuvieron de parte de la Nasa.
El tiempo utilizado para la optimización de la parte importante fue de varios días y eran pocas líneas en C pero muchisimas en Assember.
Ejemplo de uso crítico de recursos en la cpu a nivel de Assembler es por ejemplo el increment que es equivalente en C a "++". En esta instrucción en C se puede codificar como
variable++ o ++variable
El compilador inteligente sabrá que las dos son distintas y utilizan mas o menos recursos, por lo que el tiempo de ejecución cada instrucción es totalmente distinto. Un mal compilador generará el mismo código para ambas y no será optimo. ¿Porqué?
Los compiladores por lo general la instrucción "++" generan el mismo código para ambas; donde se pierde mucho tiempo es en la verificación de límites de rango de valores y eso toma varias instrucciones en alto nivel que luego son muchísimas en Assembler, esto es lo que hace que Assembler puro es muchisimo mas rapido y por lejos, en terminos de 10x o mas.

Ahora viene la pregunta del millón de dolares: ¿Es necesario aprender Assembler y crear programas en Assembler?
Ingeniería siempre debe responder: Depende.
Si quieres ser productivo y el resultado a obtener puede demorar 10 ó 60 seg, entonces no es necesario y un buen compilador hara muy bien su trabajo.
Si el resultado que se requiere debe ser en tiempos muy acotados y se dispone de "dolares" para comprar una nueva máquina, entonces no es necesario Assembler y comprar máquina mas poderosa.
En fin. Ahora otra pregunta, la aplicación que realizaba operaciones matematicas y conservaba todos los digitos, ¿es necesario convertirla a 64bits?
Resp: No. Porque ahora se puede programar en CUDA y ejecutar en paralelo en una tarjeta de video. La cpu digamos que tiene 8 registros de uso libre y que pueden utilizarse para realizar operaciones en paralelo; una tarjeta de video (rtx 3070) tiene al menos 300x mas de registros y que ejecutan en paralelo (en realidad la cantidad de registros disponibles depende de si se trabajará con 32bits o 64bits).
Otra pregunta: ¿Existe algún área en que el tiempo es crítico? Si y muchas. No es necesario enumerarlas porque basta tener un poco de imaginación y la lista sería gigantesca.

¿Se recomienda aprender Assembler como mero aprendizaje para conocer como trabaja una cpu? Si.

Como recomendación general, aprender el lenguaje que es necesario para el área en que se está trabajando y que incida en la productividad. En el tiempo libre aprender si se quiere algún otro lenguaje, quien sabe si se le da el golpe a la liebre.

Descubrir cuál es el error en la codificación en Assembler requiere tanto tiempo que es mejor re-codificar todo de nuevo.

Anécdota: A comienzo de la década de 1990 conocí a una persona por casualidad y de "metiche" por mi parte. Mientras esperabamos en una fila para ser atendidos, vi "sin querer" que estaba codificando en Assembler x86 y me puse a "sapear" sobre su hombro y en determinado momento le digo que la manera en que codificaba hacia muy lenta la ejecución. Me miro sorprendido, nos presentamos y me pidió que re-hiciera el código de manera que ejecutara de la manera mas rapida posible. Semanas despues me fue a visitar a mi trabajo y me dio las gracias porque efectivamente el código ejecutaba varias centenas mas rapido que el original. Me explico para que era y quede estupefacto por el area en que se utilizaba. Despues de eso, me pasaba trozos de codigo para que lo re-codificara y ejecutara lo mas rapido posible.

La NASA hizo publico mucho tiempo atrás el código de las computadora de la nave Apollo. Es interesante revisarlo conceptualmente y maravillarse que está todo en Assembler. Al revisar el códigoe puede dar cuenta de porque no es tan facil llegar a la luna y tocar su superficie.

Saludos
p.d.: Optimo y rapido no es lo mismo.
 
Arriba