Hacer que el enlazador use el banco 0 en modo reubicable

3

Estoy intentando crear un proyecto de ensamblaje con MPASM / MPLINK para PIC16F628A. Se recomienda a los microchips que es mejor quedarse en el banco 0 y cambiar cada vez que desee un banco diferente, y luego volver al banco 0 (para minimizar el cambio de banco). Por eso quiero poner la mayoría de los registros de archivos GPR en el banco 0. También los registros SFR más utilizados están en bank0. Sin embargo, el enlazador está tratando de ajustar los datos a partir del banco de datos más pequeño que es GPR en el banco 2. No hay manera de decirle al enlazador que comience a rellenar desde el banco 0, excepto que el banco 2 esté protegido en la secuencia de comandos del enlazador. Debería haber una mejor manera ...

ACTUALIZACIÓN: Para aquellos que no entendieron la pregunta (o no quisieron): "Cómo reservar memoria en el banco 0 para direcciones PIC16F628A de 0x20 a 0x6F en modo de código reubicable en más de un archivo".

Lo que intenté:

1.

file1.asm

FirstBank   udata_ovr 0x20
register1  res 1
register2  res 1

file2.asm

FirstBank   udata_ovr 0x20
register3  res 1
register4  res 1

Por supuesto que no lo hace porque register1 se superpone con register3. Necesito que register3 se coloque en un banco no utilizado.

2.

file1.asm

FirstBank   udata
register1  res 1
register2  res 1

file2.asm

FirstBank   udata
register3  res 1
register4  res 1

Esto pondrá todos estos registros en bank2

3.

file1.asm

FirstBank   udata   0x20
register1  res 1
register2  res 1

file2.asm

FirstBank   udata   0x20
register3  res 1
register4  res 1

error del enlazador de resultados

actualización 2: La razón por la que quiero encajar mis variables en bank0 es porque los registros SPF más comúnmente usados están en el banco 0 y no necesito cambiar entre bancos cuando los uso (lo que significa menos código). Y no, la memoria compartida (70-7F) no es suficiente para ajustar todas las variables que necesito. No sería óptimo cambiar de banco cuando puedo ajustar todas las variables que uso en el 99% del código en el banco 0.

Ahora debería estar claro. Si alguien que está discutiendo mis sentimientos realmente quiere ayudar, lo apreciaré.

P.S. Supongo que me perdí la muy importante palabra clave "modo reubicable", así que me disculpo por eso. Pero por favor, mantenga sus comentarios / respuestas sobre el tema. Si algo no está claro, pregunte y trataré de cambiar la pregunta para que sea más claro. Gracias a todos los que realmente quieren ayudar.

    
pregunta NickSoft

3 respuestas

5

Esto se puede hacer usando directivas tanto en la fuente del ensamblador como en el script del vinculador. Cuando utiliza la primitiva udata , la etiqueta se convierte en el nombre de la sección.

Considere los siguientes archivos de origen de ejemplo similares a los que ha proporcionado:

file1.asm

SomeSection   udata
    register1  res 1
    register2  res 1

SomeOtherSection   udata
    register5  res 1
    end

file2.asm

SomeSection   udata
    register3  res 1
    register4  res 1
    end

En file1.asm , habrá dos secciones de salida generadas por el ensamblador llamadas SomeSection y SomeOtherSection . Puede verificar esto activando el archivo del mapa de salida y mirando los nombres de las secciones enumeradas.

El siguiente paso es decirle al enlace dónde se deben colocar esas secciones en la memoria, esto requiere un cambio a la secuencia de comandos predeterminada del vinculador.

Localice y copie el script de vinculador predeterminado para su dispositivo ( 16f627a_g.lnk ) en el directorio de su proyecto y agréguelo a la configuración del proyecto Linker Script .

En la parte inferior de la secuencia de comandos del vinculador, verás un conjunto de especificadores SECTION como este:

SECTION    NAME=PROG       ROM=page            // ROM code space
SECTION    NAME=IDLOCS     ROM=.idlocs         // ID locations
SECTION    NAME=DEVICEID   ROM=.device_id      // Device ID
SECTION    NAME=DEEPROM    ROM=eedata          // Data EEPROM

Agregue sus propios nombres de sección aquí y el banco de RAM de destino.

SECTION    NAME=SomeSection RAM=gpr0
SECTION    NAME=SomeOtherSection RAM=gpr2

Puede verificar en el archivo de salida del mapa que sus variables se han colocado en la ubicación correcta. Del ejemplo anterior, los registros 1-4 entran en gpr0, el registro5 entra en gpr2.

    
respondido por el Austin Phillips
2

El udata_shr debería hacer lo que quieres. Consulte el manual de ensamblador / enlazador sección 4.64:

  

Esta directiva declara el comienzo de una sección de compartida   datos sin inicializar. Si no se especifica la etiqueta, la sección se llama   .udata_shr. La dirección de inicio se inicializa a la especificada   Dirección o se asignará en el momento del enlace si no se especifica una dirección.    Esta directiva se usa para declarar variables que están asignadas en la RAM   que se comparte en todos los bancos de RAM (es decir, RAM no bancarizada). Ningún código puede   Se generará en este segmento. La directiva res debería ser usada para   reserva espacio para datos.

    
respondido por el PetPaulsen
2

Quiero agregar una solución no óptima que realmente funcione, pero no es tan conveniente. Opción 1 Si todas las variables que deben estar en el banco 0 se enumeran en un solo archivo y se exportan con "GLOBAL", una sección de udata con una dirección fija haría el trabajo. Todavía estoy esperando si alguien sugiere algo que permita abordar el banco 0 desde varios archivos (objetos) de ensamblador. Tal vez haya una forma de pasar el nombre del banco como se menciona en la secuencia de comandos del vinculador o alguna forma de forzar que el vinculador comience con el banco 0.

opción 2: Por supuesto, si no usa bank2 en absoluto, se puede usar un "marcador de posición" para asignar todos los GPR en bank2:

placeHolder   udata    0x011F
              res    48

opción 3: Lo más parecido a una solución es nombrar todas las secciones de udata en los archivos con el mismo nombre y (muy importante) rellenar el espacio a más de 48 bytes:

en file1.asm

FirstBank    udata
variable1    res   1
variable2    res   1
             res   48    ; this needs to be decreased if data in this section becomes
                         ; Larger than 32 bytes. The idea is to keep
                         ; data+padding > 48 so the section cat't fit in bank 2

en file1.asm FirstBank udata     variable3 res 1     variable4 res 1

Pero estas son solo soluciones, no soluciones reales.

ACTUALIZACIÓN: Tenga en cuenta que no debería tener que preocuparse por un usuario que comience desde un banco distinto de 0 con MCU que tienen todos los bancos del mismo tamaño. Por ejemplo, para el enlazador PIC16F648A se inicia desde el banco 0.

    
respondido por el NickSoft

Lea otras preguntas en las etiquetas