Como se menciona tanto a C como Asm me pareció mejor dejarlo en este sector general de microcontroladores Pic, si es mejor otro subforo algún moderador lo moverá hacia allí.
Esta explicación se limita solamente al compilador C18 bajo entorno MPLAB IDE y no abarca las diferencias que puedan existir para otros compiladores C.
Empecemos con una breve síntesis:
Embeber código Asm en C es muy diferente a escribir instrucciones Asm “in line” del tipo: _asm ….. _endasm
Las directivas anteriores para el compilador son limitadas y no se permite todo el repertorio de instrucciones que ofrece el microcontrolador. En cambio Asm embebido, mezclado o enfrascado en un compilador C equivale a poder integrar un código escrito en Asm, un programa completo en Asm, rutinas específicas en Asm, etc y llamadas desde C como a una función.
Como ejemplo se podría desarrollar 99% Asm con 1% C sobre un compilador C, a la inversa o en cualquier porcentaje que decidiera el desarrollador. Es interesante tenerlo presente y aunque no es nada nuevo, tal vez no es del todo aplicado o conocido y lo más importante es la simpleza de su implementación siguiendo solamente las directivas especificas que requiere el compilador C. De esto se trata.
¿Ventajas? Las siguientes:
1- Las ventajas sólo las puede encontrar el desarrollador según el proyecto, en mi caso no hay código en C18 que no tenga su cuota de rutinas con código Asm, pero es una decisión de cada programador.
2- Una rutina en Asm puede ser en muchos casos más reducida, compacta y optimizada ya que la escribe directamente el desarrollador y no el analizador o intérprete de lenguaje del compilador.
3- El C18 no hace uso del 100% del repertorio de instrucciones del microcontrolador, podríamos decir que un porcentaje de instrucciones quedan marginadas. Un claro ejemplo son:
CPFSEQ
CPFSGT
CPFSLT
Las anteriores instrucciones fueron incorporadas en los 18Fxxxx, especiales para comparaciones, y el C18 (por lo menos hasta la versión 3.32) no las utiliza en ningún momento.
4- Para los programadores en Asm que comienzan en C es una forma de seguir con Asm e ir incorporando rutinas en C a medida que avanzan con el lenguaje o las librerías especializadas del C en sus proyectos Asm (desde asm pueden ser llamadas funciones en C)
5- Para los programadores 100% C y quieren ir incursionado en Asm o utilizar librerías en Asm enlatadas en C.
6- Fin del eterno dilema: todo “C” o todo “Asm”. La tercera opción es que pueden trabajar juntos y de maravilla.

Requisitos: MPLAB IDE y tener instalado C18
Seleccionar C18 Toolsuite y crear un proyecto, salvando una plantilla con extensión .c y otra con extensión .asm
==================================================================================
// Desde el archivo .C
#include <p18cxxx.h>
// Declaración de variables globales
#pragma udata
char Registro_1;
char Registro_2;
char Registro_3;
// Prototipos de funciones
void Funcion_C(void);
// Declaración de las rutinas externas en ensamblador
extern void RUTINA_1(void);
extern void RUTINA_2(void);
extern void RUTINA_3(void);
// sección de código
#pragma code
void main(void){
// Desde main se llama a diferentes rutinas de ensamblador
RUTINA_1();
RUTINA_2();
RUTINA_3();
//…
//…
}
void Funcion_C(void){
// Esta función de C es llamada desde Asm
//…
//…
}
==================================================================================
;Desde el archivo .ASM:
; El clásico include según microcontrolador
#include <p18f252.inc>
; Definiciones:
; Acá se pueden agregar definiciones, configuraciones como
; se hace habitualmente en ensamblador
; ......
; ......
; ......
; Variables:
; Las variables globales declaradas desde C pueden ser utilizadas desde las
; Rutinas Asm siempre y cuando sean declaradas en la cabecera del archivo Asm o
; bien desde un archivo .inc como externas:
; Ejemplo de variables char declaradas en C y utilizadas en Asm:
EXTERN Registro_1
EXTERN Registro_2
EXTERN Registro_3
; .....
; .....
; Código:
; Previo a rutinas de código Asm, debe declararse la directiva para el
; compilador:
UDATA_ACS
CODE
; La directiva CODE puede ampliarse si es necesario con el direccionamiento de memoria
; donde deberían iniciarse las secciones de código, para los programadores en Asm sería
; el reemplazo de la conocida directiva ORG 0xXX
SECTOR_1 CODE 0x0800
; SECTOR_1 puede ser cualquier nombre que identifique una dirección de memoria donde
; comenzará a ensamblarse el código, en este ejemplo a partir de la dirección 0x800.
; Para que no se genere error al compilar debe ser una dirección diferente a cualquiera
; que haya sido previamente declarada en C que direccionen un mismo sector de memoria.
; Rutinas:
; RUTINA_1 o cualquier otro nombre, es la clásica etiqueta de Asm que hace
; referencia a una sección de código. Desde C18 es vista como una llamada a
; una función. Se finaliza con un RETURN y debe estar siempre presente la
; directiva GLOBAL <Nombre de rutina> en este caso GLOBAL RUTINA_1.
RUTINA_1:
RCALL Algoritmo
; ......
; ......
RETURN
GLOBAL RUTINA_1
; El código asm que sigue a RUTINA_1 puede llamar a otras rutinas dentro de Asm
; como se hace habitualmente con CALL o RCALL. Puede ser una rutina o bien un
; programa completo en asm.
; También desde el código ASM pueden ser llamadas Funciones de C, ejecutarse, retornar
; y continuar la rutina en ASM, para esto hay que declarar previamente (en la cabecera
; del archivo asm o creando un archivo .inc) la directiva "extern" a la función que luego será
; invocada desde alguna rutina asm.
; En la cabecera del archivo Asm de esta forma:
; EXTERN <Nombre de la función de C>
; desde una rutina:
; CALL <Nombre de la función de C>
; Ejemplo:
EXTERN Funcion_C
; Esta rutina "Algoritmo" es llamada solamente por RUTINA_1
; dentro de Asm por lo tanto no necesita la directiva GLOBAL
; pero hace una llamada a una función escrita en C y retorna.
; La función en C está declarada como externa y es tomada desde
; el archivo Asm como otra etiqueta más dentro del programa.
Algoritmo:
CALL Funcion_C
; ......
; ......
RETURN
; RUTINA_2 y RUTINA_3 son ejemplos de rutinas que pueden ser llamadas
; por una o distintas funciones desde C
RUTINA_2:
; ......
; ......
RETURN
GLOBAL RUTINA_2
RUTINA_3:
; ......
; ......
RETURN
GLOBAL RUTINA_3
; Como todo programa en ASM no se debe olvidar finalizarlo con end
END
;=================================================================================
; Las rutinas o programas en Asm pueden seguir utilizando también las directivas EQU,
; CBLOCK ... ENDC, etc, siempre teniendo precaución de no cambiar algún dato utilizado
; por alguna variable de C
; Para mayor información consultar "Mixing C and Assembly" del manual MPLAB® C18
; C COMPILER USER’S GUIDE.
Adjunto el archivo C18 de lo explicado anteriormente para compilar. No tiene código, puesto que se trata de un ejemplo explicativo, es sólo para despejar alguna duda desde la práctica.
Luego de compilar se debe hacer correr con el MPLAB SIM activado y comprobar como interactúan las llamadas entre C y ASM.
Saludos Willy.-