Autor Tema: Acerca del lenguaje en ensamblador ASM  (Leído 2486 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Acerca del lenguaje en ensamblador ASM
« en: 17 de Septiembre de 2017, 17:24:14 »
Hola amigos.
Bueno mi pregunta es "universal" es acerca del ASM, ya que este fin de semana trate de programar un micro de TI, el mps4302553, e ingenuamente  :-)  pensé que el ASM de ese micro seria igual o prácticamente igual xD al ASM de los pic16f o pic18f, pero no es así.
En los pics se utiliza el registro de trabajo W para setear registros, en cambio en el micro que trate de usar no trabaja de la misma forma (por lo que averigüe tiene 16 registros especiales y hay que empezar a jugar con ellos para setear registros).

Mi pregunta en si es:
¿A que se debe que el ASM no sea "tan" universal como C, en el sentido de que prácticamente al cambiar de micro (si partes por pics en ASM) debes aprender un ASM distinto? ¿Es por  el tipo de arquitectura, como RISC, CISC, Von neuman, Harvard, ARM, etc?

PD: los nemotecnicos son "relativamente" parecidos xD

Toda información sera agradecida

Saludos!!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Acerca del lenguaje en ensamblador ASM
« Respuesta #1 en: 17 de Septiembre de 2017, 18:35:32 »
Es porque ASM es basicamente escribir los opcodes del micro, nomas que en ASM se le da un mnemonico a esos opcodes asi es mas simple de recordar.

El problema de ASM, dejando de lado los diferentes compiladores. Es que requieren gran conocimiento de la arquitectura del microcontrolador que sea. Sin irte a otro fabricante, podras distinguir que programar para PIC16 y programar para PIC18 es totalmente distinto. Es cierto que tenes un W en ambos, pero en uno los SFR ( Special Funtion Register, como los del TMR ) estan junto a los GPR, es decir a la RAM que uno usa. Distinto es el PIC18, que el banco 15 son los SFR y pueden ser accedidos desde cualquier banco. Los PIC18 posee tambien otro set de instrucciones por lo que al planificar un salto con un GOTO, en el PIC16 solo pensas en 1 solo lugar, pero en los PIC18 son 2. Otro tema es que los PIC16/18 tiene un stack por hardware, mientras que otros micros usan la RAM (dsPIC/MSP430/CortexM/AVR) para su stack de saltos.

El que tengas un lenguaje de alto nivel permite no tener que pensar en todo esto. Como traer una variable y donde ubicarla, que registros usar para operar, si quiero realizar un salto como lo hago, etc. Esas son las ventajas de C. Te olvidas de todo esto. El compilador es quien se toma todo el trabajo de buscar las instrucciones para hacerlo para un PIC16/PIC18/MSP430/etc
Ademas que ASM sea diferente hace que tampoco sea portable.

En si el que debas programar distinto es culpa de la arquitectura, pero no me refiero a porque sea Von neumann o Hardvard, RISC o CISC, ya que dentro de las harvard tenes distintas formas de operar. Ejemplo los AVR/ARM vos tenes que traer el dato a un registro, operar en esos registros y luego llevarlo de nuevo a la RAM. En los PICs es distinto observaras que su set de instrucciones te permite operar directamente sobre cualquier posicion de la RAM. Ambos realizan lo mismo, pero de distinta forma.

En resumen, ASM es lindo en el sentido que te ayuda o aprendes como es que funciona el micro internamente, tambien en el caso que necesites algo critico en tiempo y que debas saber de forma exacta el tiempo que se tarda en ejecutar eso, o hacerlo lo mas rapido posible. Tambien te podria llevar a rebuscartelas para crear ciertas operaciones que sean mas simples para el micro (conociendo lo que el micro puede realizar ) y ahorrar ciclos. Pero mas alla de eso, no existen demasiadas ventajas. Ya que es lento de programar a comparacion de un lenguaje de alto nivel y mas facil de cometer algun error.

Una explicacion burda de lo que digo de como rebuscartelas para crear algo mas simple, Si yo tengo que multiplicar por 5. Tal ves en C ya posea una funcion que multiplique por cualquier numero, en la cual se le envian los 2 numeros y trae el resultado. Tal ves eso lleve unos 200 ciclos. Pero yo no necesito algo tan general. Y puedo pensarlo como lo haria con lo mas simple que tengo y que puede realizar el micro ( sumas y desplazamiento )

Código: C
  1. for (i = 0, total = 0; i<5; i++) total += var;

o

Código: C
  1. total = (var << 2) + var;

Y lograr en 10 ciclos lo que antes me tardo 200. Pero eso nunca deja de ser mas legible y mantenible que:

Código: C
  1. total = var * 5;

O tal ves tenes un multiplicador por hardware y este ultimo es lo mas rapido. Pero eso no lo sabrias si es que no tenes conocimiento de la arquitectura/modulos del micro.

----------------

A lo que apuntamos con los lenguajes de alto nivel es tener legibilidad, que sea de facil mantenimiento, y en casos de librerias portabilidad. Bastante complicado con tener solo ASM.
« Última modificación: 17 de Septiembre de 2017, 18:42:39 por KILLERJC »

Desconectado JuanjoPic

  • PIC12
  • **
  • Mensajes: 97
Re:Acerca del lenguaje en ensamblador ASM
« Respuesta #2 en: 17 de Septiembre de 2017, 20:37:47 »
Gracias por comentar KILLERJC!!

Entonces como el ASM no es estandarizo creo que dentro de todo los "ASM" seria mejor aprender el de los ARM, por que hay muchos micros, y de distintos fabricantes (menos Microchip),  que están usando esa arquitectura actualmente. Si bien están los cortex M0, M3 ,M7, etc ; no creo que sean tan distintos (ono?) en su programación en ASM.

¿Tiene sentido lo que he expuesto?


Desconectado tsk

  • PIC18
  • ****
  • Mensajes: 258
Re:Acerca del lenguaje en ensamblador ASM
« Respuesta #3 en: 17 de Septiembre de 2017, 21:52:20 »
Aun entre los mismos ARM Cortex MX vas a encontrar diferencias que pueden ser sutiles, ya que no todos soporta el mismo set de instrucciones. Además va más aya de crear un estándar ya que cada uno tiene distintas opiniones de como hacer las cosas, así como por cuestiones de Propiedad Intelectual.

Pero para ponerlo en otras palabras.

RISC proviene de Reduced Instruction Set Computer y RISC de Reduced Instruction Set Computer.

Von Neumann y Hardvard esta más de lado de donde colocas los datos y donde colocas las instrucciones.

En el caso de Von Neumann tanto las instrucciones como los datos comparte un mismo bus, en el caso de Hardvard datos e instrucciones tiene su propio bus.

Entonces con esto podrías realizar la clasificación:

Por ejemplo los PIC16 cuentan con un número reducido de instrucciones, entonces es RISC y también el bus de datos está separado del bus de instrucciones lo cual lo hace tener una arquitectura Hardvard.

ARM, tiene un conjunto reducido de instrucciones (RISC), pero puedes encontrar tanto Von Neumann como Hardvard, por ejemplo ARM7 es Von Neumann pero AMR9 es Hardvard.

El procesador que usamos en nuestras PC son CISC + Von Neumann.

El porque las instrucciones son distintas es por lo que se conoce como ISA o Instruction Set Architecture y a esto es lo que comúnmente conocemos como ARM, MIPS, x86, i386, PIC16, etc. y dependiendo de su complejidad es que se clasifican en CISC o RISC.

El ISA, es por así decirlo una capa de abstracción entre el hardware y el programador. Tu como programador no necesitas conocer como trabaja internamente el procesador, y los nemotécnicos son los que son traducidos a instrucciones que el MCU entiende y esas instrucciones las puedes ver cuando decompilas un binario.

xc16

Por orden de aparición: Dirección de la instrucción, opcode, instrucción ASM
Código: [Seleccionar]
0000096a <_main>:
 96a: 04 00 fa    lnk       #0x4
 96c: 00 0f 78    mov.w     w0, [w14]
 96e: 11 07 98    mov.w     w1, [w14+2]
 970: 24 89 28    mov.w     #0x8892, w4
 972: 84 1f 78    mov.w     w4, [w15++]
 974: 42 fc 07    rcall     0x1fa <__printf_s>
 976: 8f 87 e9    dec2.w    w15, w15
 978: 00 02 eb    clr.w     w4
 97a: 04 00 78    mov.w     w4, w0
 97c: 00 80 fa    ulnk     
 97e: 00 00 06    return   
 

gcc (x86_64)

Código: [Seleccionar]
000000000040052d <main>:
  40052d: 55                    push   %rbp
  40052e: 48 89 e5              mov    %rsp,%rbp
  400531: 48 83 ec 10          sub    $0x10,%rsp
  400535: 89 7d fc              mov    %edi,-0x4(%rbp)
  400538: 48 89 75 f0          mov    %rsi,-0x10(%rbp)
  40053c: bf e4 05 40 00        mov    $0x4005e4,%edi
  400541: b8 00 00 00 00        mov    $0x0,%eax
  400546: e8 c5 fe ff ff        callq  400410 <printf@plt>
  40054b: b8 00 00 00 00        mov    $0x0,%eax
  400550: c9                    leaveq
  400551: c3                    retq   
  400552: 66 2e 0f 1f 84 00 00 nopw   %cs:0x0(%rax,%rax,1)
  400559: 00 00 00
  40055c: 0f 1f 40 00          nopl   0x0(%rax)

De lo anterior puedes inferir que también se tiene que añadir otra clasificación a los ISA que tiene que ver con el tamaño de la instrucción en términos si es fija o variable. El tamaño de la instrucción en los pic24 es fijo a 24 bits, tanto en los ARM como los x86 son de tamaño variable. Y otra clasificación es si es big endian o little endian.

Una forma muy práctica de ver esto último es tras añadir una variable tipo int

Código: C
  1. int k = 0xCC0110C1;

Con GCC en la PC

Código: ASM
  1. 40053c: c7 45 fc c1 10 01 cc    movl   $0xcc0110c1,-0x4(%rbp)

Se observa que es Little Endian (c1 10 01 cc)


C fue creado para evitarle al programado lidiar con muchos de estos detalles y crear un lenguaje portable entre arquitecturas, al igual que los Sistemas Operativos fuero creados para administrar los recursos de las computadoras de forma transparente al programador y al usuario final.


 

anything