Dispositivos de Control. Guía de Practicas.
Practica 3 – Llamado a Funciones en Ensamblador desde C. Objetivo.
El Alumno aprenderá a reutilizar las subrutinas que realiza en ensamblador en lenguaje C, para de esta manera tener su propia biblioteca de rutinas que pueda utilizar en otros programas. Introducción.
El lenguaje ensamblador es una de las erramientas más poderosas que tiene el dise!ador de sistem sistemas as embebid embebidos, os, "a que este este nos permite permite manejar manejar de manera manera #ptima #ptima el ard$a ard$are re mucas veces limitado que tenemos. %as rutinas en ensamblador ensambl ador nos dan in&ormaci#n " control sobre el tiempo de ejecuci#n del c#digo c#digo,, " los recursos recursos utilizado utilizados, s, como como son la memori memoria a tanto tanto de progra programa ma como como de datos datos necesaria para realizar una tarea. Desgraciadamente, el lenguaje ensamblador es muco más complicado de programar, por lo que desarrollar una aplicaci#n enteramente en ensamblador puede generarnos un ma"or costo debido a los tiempos de dise!o, puesta a punto, " llegada al mercado. En cambio, los lenguajes de alto nivel como el C, nos proporcionan tiempos de desarrollo " llegada al mercado más rápidos, a costa de tener menor control sobre los recursos. El so&t so&t$a $are re de un siste sistema ma embeb embebido ido puede puede dividi dividirs rse e en ' parte partes. s. %a prime primera ra es la aplica aplicaci# ci#n n propia propiament mente e dica dica (medic (medici#n i#n de variabl variables, es, contro controll de motor motores, es, comunic comunicaci aci#n #n de datos, etc.)* esta parte de la aplicaci#n, normalmente se ve sujeta a limitaciones en cuanto tiempo de ejecuci#n, por lo que es más práctico, " en ocasiones necesario desarrollarla en ensamblador. %a segunda parte del c#digo, es la inter&az de usuario. +ormalmente las inter&aces de usuario son mu" complejas, "a que deben de presentar la in&ormaci#n generada por el sistema de tal &orma que sea &ácil " agradable de leer, así como pedir datos de entrada o ajustes al usuario, " evitar que dicos valores sean incorrectos. Debido a que esta secci#n del c#digo no suele estar sujeta a restricciones de tiempo de ejecuci#n, es pre&erible desarrollarlas en un lenguaje de alto nivel, a n de reducir nuestros tiempos de programaci#n. De lo anterior nos es claro que poder mezclar ambos tipos de programación nos beneficiaria, ya que podríamos obtener las ventajas de cada uno de los lenguajes. El PSo Designer nos permite usar subrutinas desarrolladas en ensamblador desde lenguaje , por medio de la directiva #pragma fastcall16 que nos permite llamar a funciones en ensamblador desde . Conexiones.
onecta tu !D al Puerto " del PSo, y tu teclado matricial al Puerto # como se $izo en la Practica ". %o se necesitar& m&s $ard'are.
-C. Edgar -auricio -auri cio omero %#pez
Dispositivos de Control. Guía de Practicas.
Desarrollo.
(niciaremos creando un proyecto en y le !lamaremos )Practica*a+. En este Proyecto usaremos el módulo de !D y el de !ED en caso de que el !D tenga !uz-, no utilizaremos la barra y lo conectaremos al puerto " con los mismos par&metros de la pr&ctica anterior. El eclado /atricial se conectar& al puerto #0 este puerto deber& configurarse como Pull12p. eclea el Siguiente ódigo en el arc$ivo main. //---------------------------------------------------------------------------// C main line //---------------------------------------------------------------------------#include
#include "PSoCAPI.h" #include "Su!rutinas.h"
// part specific constants and macros // PSoC API definitions for all User odules // Incluimos nuestras su!rutinas
char Unidades ecenas Centenas$ %ecla$ int &alor$ 'oid main('oid) * +C,Start()$ +,Start()$ +,n()$ Unidades 010$ ecenas 010$ Centenas 010$ +C,Position(11)$ +C,PrCStrin2("3umero4 ")$ +C,Position(51)$ +C,PrCStrin2("&alor 6e74 ")$ hile(5)* +C,Position(18)$ +C,9riteata(Centenas)$ +C,9riteata(ecenas)$ +C,9riteata(Unidades)$ %ecla 1$ hile (%ecla 1)* %ecla :ead;e()$ if ((%ecla > 0=0) (%ecla <010))* if (%ecla 00)* &alor 511?(Centenas-010)@51?(ecenas-010)@(Unidades-010)$ +C,Position(555)$ +C,Pr6e7Int(&alor)$ %ecla 1$ Centenas ecenas$ ecenas Unidades$ Unidades %ecla$
!ee el código y e3plica que crees que $ace.
4$ora ve al men5 )6ile+ y selecciona %e' 6ile, o Presiona el ícono de )4rc$ivo %uevo+ en la barra de men5s. e aparecer& una ventana pidi7ndote el tipo y nombre del arc$ivo que vas a crear. Selecciona ).asm 6ile+ y dale como %ombre )Subrutinas+.
-C. Edgar -auricio omero %#pez
Dispositivos de Control. Guía de Practicas.
En este nuevo arc$ivo vamos a crear nuestras subrutinas en ensamblador. eclea el siguiente código en este nuevo arc$ivo. $ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, $ Archi'o de Su!rutinas $ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, include "m8c.inc" include "memor.inc" include "PSoCAPI.inc"
$ part specific constants and macros $ Constants B macros for S/+ and Compiler $ PSoC API definitions for all User odules
ilas4 eDu Columnas4 eDu :oE4 eDu :oF4 eDu :oG4 eDu :o54 eDu ColE4 eDu ColF4 eDu ColG4 eDu Col54 eDu ;ePort4 eDu P:%5:
171 171 1!11111555 1!11115155 1!11115515 1!11115551 1!55511111 1!55151111 1!51551111 1!15551111
e7port :ead;e e7port ,:ead;e area te7t(: :+) $ -------------------------------------------------------------------------$ Su!rutina de +ectura de un %eclado atricial en el Puerto ";ePort" $ :e2resa en el Acumulador el 'alor ASCII de la tecla presionada $ sta su!rutina modifica el 'alor del Acumulador $ sta su!rutina reDuiere Due el puerto este confi2urado como Pull-Up $ -------------------------------------------------------------------------.section macro Asi2nCol&alues mo' re2H;ePort Jilas $ Acti'o todas las ilas mo' A re2H;ePort $ +eo el Puerto cmp A Col5 KL Columna5 cmp A ColG KL ColumnaG cmp A ColF KL ColumnaF cmp A ColE KL ColumnaE mo' A1711 ret ColumnaE4 mo' A MF ret ColumnaF4 mo' A MG ret ColumnaG4 mo' A M5 ret Columna54 mo' A M1 ret endm :ead;e4 ,:ead;e4 mo' re2H;ePortJColumnas $ Acti'o todas las Columnas mo' A re2H;ePort $ +eo el Puerto cmp A :o5 KL ila5 cmp A :oG KL ilaG cmp A :oF KL ilaF cmp A :oE
-C. Edgar -auricio omero %#pez
Dispositivos de Control. Guía de Practicas. KL ilaE mo' A1711 ret ila54
// C5 CG CF CE Asi2nCol&alues 050 0G0 0F0 0A0
ilaG4 Asi2nCol&alues 0E0 0N0 0O0 00 ilaF4 Asi2nCol&alues 0Q0 080 0=0 0C0 ilaE4 Asi2nCol&alues 0?0 010 0#0 00 .endsection
Este programa no es muy diferente a como $icimos nuestra subrutina en la pr&ctica anterior. Sin embargo $ay algunas diferencias que $acen posible llamarlas desde . !a primera est& en las líneas "#, "", 89 y 8: del programa.
%as Primeras dos lineas sirven para que todos los arcivos del pro"ecto tengan acceso a la subrutina /ead0e"1 que icimos. Aquí puedes ver que la e2portamos ' veces. 3na vez con el nombre /ead0e"1 " otra con el nombre /4ead0e"1 la razon de e2portarlo de esta manera, es que cuando llamamos a una subrutina en C, el compilador agrega de manera automática el carácter /41 al principio del combre cuando compila el programa. De esta manera, cuando nosotros usamos la subrutina /%ED 45n()1 en C, al compilarla " pasarla a ensamblador queda traducida como /call 4%ED45+1. E2portamos nuestra subrutina con ambos nombres, para poder llamarla tanto de C como de Ensamblador por medio del mismo nombre, "a que el ensamblador no agrega el gui#n bajo al nombre. En las ultimas dos lineas podemos ver que nuestra subrutina puede ser llamada con cualquiera de los dos nombres, "a que ambas etiquetas tienen el mismo valor. Es ecomendable que cada subrutina que creemos se encuentre dentro de las directivas /.section1 " /.endsection1 de esta manera, si una subrutina en particular no es utilizada, su c#digo no se agregara a nuestro programa, por lo que usaremos menos memoria de codigo. ;uelve al men5 )6ile+ y selecciona %e' 6ile, o Presiona el ícono de )4rc$ivo %uevo+ en la barra de men5s. e aparecer& una ventana pidi7ndote el tipo y nombre del arc$ivo que vas a crear. Selecciona ).$ 6ile+ y dale como %ombre )Subrutinas+. Esto creara un arc$ivo de cabeceras de . En este le diremos al compilador de que subrutinas en ensamblador e3isten, y como funcionan.
-C. Edgar -auricio omero %#pez
Dispositivos de Control. Guía de Practicas. eclea las siguientes líneas en este arc$ivo< // efinicion pra2ma para las su!rutinas en ensam!lador #pra2ma fastcall5O :ead;e // Ca!eceras de las Su!rutinas en ensam!lador e7tern R% :ead;e('oid)$
!a primera línea le dice al compilador que e3iste una función $ec$a en ensamblador que utiliza los m7todos fastcall#= para pasado de argumentos desde y $acia . !a segunda línea le indica que nuestra subrutina se encuentra en un arc$ivo diferente a nuestro programa principal e3tern-, regresa un dato tipo >?E y no es necesario pasarle ning5n par&metro void-. !os m7todos de pasado de argumentos mediante fastcall#=, establecen la forma en que una subrutina en ensamblador recibe y entrega par&metros cuando es llamada desde . ;eamos los siguientes ejemplos< Declaración en C
void /i6uncionvoidvoid /i6uncionc$ar Param#void /i6unciónc$ar Param#, c$ar Param"void /i6unciónint Param#void /i6uncionptr Param#c$ar /i6uncionvoidint /i6uncionvoid-
Parámetros de Entrada en Ensamblador
%inguno 4 @ Param# 4 @ Param# A @ Param" 4 @ B Param# !S>A @ C Param# /S>A @ B Param# !S> 4 @ C Param# /S>%inguno %inguno
ptr /i6uncionvoid-
%inguno
void /i6uncionc$ar Param#, int Param"-
FSP1*G @ Param# FSP1HG @ B Param" !S>FSP18G @ CParam" /S>FSP1*G @ B Param# !S>FSP1HG @ C Param# /S>FSP18G @ B Param" !S>FSP1=G @ CParam" /S>FSP1*G @ B Param# !S>FSP1HG @ C Param# /S>FSP18G @ B Param" !S>FSP1=G @ CParam" /S>-
void /i6uncionint Param#, int Param"-
void /i6uncionptr Param#, ptr Param"-
Resultados en Ensamblador
%inguno %inguno %inguno %inguno %inguno 4 @ esult$ar 4 @ B Param# !S>A @ C Param# /S>A @ B Param# !S> 4 @ C Param# /S>%inguno
%inguno
%inguno
En la tabla se puede ver que cuando los par&metros de entrada de la función son # o " bytes, se pasan por medio de los registros internos, cuando los datos son m&s de " bytes, se pasan por medio del stacI, guardando los par&metros en el orden inverso al que se define en la cabecera de , y si alguno de los datos es de m&s de un byte, se comienza a guardar primero los bytes mas significativos, y por 5ltimo los menos significativos. uando los valores de retorno son de m&s de " bytes, se deben regresar por medio de punteros o variables globales. Si la rutina se utiliza en ensamblador, es necesario volver el stacI al tamaJo adecuado despu7s de llamar a una subrutina. Por ejemplo una subrutina que en tiene la cabecera< e7tern 'oid iuncion(int ato5 int ?ptratoG)$
En ensamblador se llamaría de la siguiente manera<
-C. Edgar -auricio omero %#pez
Dispositivos de Control. Guía de Practicas. mo' A >ptratoG push A mo' A
$ S ptratoG $ +S ptratoG $ S ato5 $ +S ato5 $ +lamado a la funcin $ :e2resa el StacT a su tamao ori2inal
ompila y corre el programa. KLace lo que esperabasM NNNNNNNNNNNNNNN KPor qu7M
ompón el ódigo del Programa, de tal manera que se adquieran los datos del teclado de forma correcta. 4$ora, crea * subrutinas en ensamblador, que puedan llamarse desde . !as adenas de entrada de estas subrutinas deber&n poder trabajar con las cadenas, sin importar en que p&gina est7n. !a primera deber& comparar " cadenas null 1 terminated- y regresar # si cadena# inicia con la cadena". Deber& estar declarada en como< e7tern R% StrStarts9ith(char ?Cadena5 const char ?CadenaG)$ !a segunda deber& convertir una cadena null 1 terminated- que contenga caracteres, n5meros y símbolos, a una cadena que contenga solo n5meros símbolos y letras min5sculas. Deber& estar declarada en como< e7tern ?Ptr +oerStr(char ?Cadenauente char ?Cadenaestino)$
!a 5ltima deber& convertir un arreglo de * caracteres num7ricos 4S(( a un n5mero binario entre O y :::. El byte " del arreglo deber& contener las unidades, el uno las decenas y el cero las centenas0 en caso de que alguno de los caracters no corresponda a un n5mero 4S((, se deber& regresar O36666. Deber& estar declarada en como< e7tern 9: Str3umGte(char ?3umeros)$
Documenta debidamente las rutinas poni7ndole comentarios e indicando al inicio de cada una, que registros modifica, y sus requerimientos de memoria en caso de tenerlos. Laz un programa en para demostrar el funcionamiento de tus funciones. !lama a este nuevo proyecto Practica*b.
-C. Edgar -auricio omero %#pez