Reputation: 157
How to declare array of constants in flash using only assembly not C?
The question says it all, I believe. Other than within the assembly code itself, I will want to access and iterate through that constant array of values.
I am using Code Composer Studio , an MSP432.
To contrast, I know how to access RAM because I know where those addresses exist, and my code is free to do whatever with them. Thus, I can do something like so:
;declare 1st RAM address:
FIRST .field 0x20000000,32
;use it:
LDR R1,FIRST
LDRB R0,[R1]
;etc.
Or if I'm accessing GPIO, I know the specific input adress(es):
;declare:
PORT1INPUT .field 0x4000C000,32
;use:
LDR R1,PORT1INPUT
LDRB R0,[R1]
But I want values from flash, contiguous, from known addresses, just like above.
UPDATE:
.thumb
.text
.align 2
;my issue or question is about this section (I think)
;don't know how or what to put here
;to declare a continguous block of
;addresses in flash, containing
;specific values
;i dont want to load just the values,
;i need to know how to start at a certain
;address
; i.e. i want to mimic an array,
; but in flash.
;i know how to initialize and mimic an
;array in RAM.
.global main
.thumbfunc main
main: .asmfunc
mainloop
;code here that starts at
;first address in flash
;containing first value
;and reads it into a register
;
;the code isn't the problem.
;i know how to do this part.
B mainloop
.endasmfunc
.end
MORE UPDATE I create a bare-bones C project in Code Composer, for the MSP432. in main(), I have:
#include "msp.h"
static const int somearr[] = { 1,2,3,4,5,6,7};
void main(void) {
int i = somearr[0];//needed so compiler would not ignore declaration
}
When I debugged it, turns out just like I wanted - a series of constants in flash , in this case situated after the code "main()", starting at flash address 0x000005D0
. And the data stored at each consecutive location after that are the int values I specified.
But I want to do that in straight assembly - not C.
The build output (would show the tool chain I imagine) is:
**** Build of configuration Debug for project 00.static.global.const.array.of.ints ****
/opt/ti/ccsv8/utils/bin/gmake -k -j 2 all -O
Building file: "../main.c"
Invoking: ARM Compiler
"/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="/opt/ti/ccsv8/ccs_base/arm/include" --include_path="/opt/ti/ccsv8/ccs_base/arm/include/CMSIS" --include_path="/home/devchu/Development/ti.robotics/tirslk_maze_1_00_00/00.static.global.const.array.of.ints" --include_path="/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/include" --advice:power=all --define=__MSP432P401R__ --define=ccs -g --gcc --diag_warning=225 --diag_wrap=off --display_error_number --abi=eabi --preproc_with_compile --preproc_dependency="main.d_raw" "../main.c"
"../main.c", line 3: warning #179-D: variable "somearr" was declared but never referenced
Finished building: "../main.c"
Building target: "00.static.global.const.array.of.ints.out"
Invoking: ARM Linker
"/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --advice:power=all --define=__MSP432P401R__ --define=ccs -g --gcc --diag_warning=225 --diag_wrap=off --display_error_number --abi=eabi -z -m"00.static.global.const.array.of.ints.map" --heap_size=1024 --stack_size=512 -i"/opt/ti/ccsv8/ccs_base/arm/include" -i"/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/lib" -i"/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/include" --reread_libs --diag_wrap=off --display_error_number --warn_sections --xml_link_info="00.static.global.const.array.of.ints_linkInfo.xml" --rom_model -o "00.static.global.const.array.of.ints.out" "./main.obj" "./startup_msp432p401r_ccs.obj" "./system_msp432p401r.obj" "../msp432p401r.cmd" -llibc.a
<Linking>
remark #10371-D: (ULP 1.1) Detected no uses of low power mode state changing instructions
remark #10372-D: (ULP 4.1) Detected uninitialized Port 1 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 2 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 3 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 4 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 5 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 6 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 7 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 8 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 9 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
remark #10372-D: (ULP 4.1) Detected uninitialized Port 10 in this project. Recommend initializing all unused ports to eliminate wasted current consumption on unused pins.
Finished building target: "00.static.global.const.array.of.ints.out"
Building files: "00.static.global.const.array.of.ints.out"
Invoking: ARM Hex Utility
"/opt/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.2.LTS/bin/armhex" --memwidth=8 --romwidth=8 -o "00.static.global.const.array.of.ints.hex" "00.static.global.const.array.of.ints.out"
Translating to Extended Tektronix format...
"00.static.global.const.array.of.ints.out" .intvecs ==> .intvecs
"00.static.global.const.array.of.ints.out" .text ==> .text
"00.static.global.const.array.of.ints.out" .cinit ==> .cinit
Finished building: "00.static.global.const.array.of.ints.out"
**** Build Finished ****
Upvotes: 1
Views: 1263
Reputation:
In C const int somearr[] = { 1,2,3,4,5,6,7};
places the data in the .rodata
segment.
To archive the same you need to place your table in this section
I do not know the code composer but gnu assembler has the .section
directive
Upvotes: 1
Reputation: 157
One way to do this, worked for me with an STM32 Nucleo-64 (Nucleo-F303RE). To keep example simple, I ran the code within the reset handler.
.syntax unified
.cpu cortex-m4
.fpu vfpv4
.thumb
.global vtable
.global reset_handler
.type vtable, %object
vtable:
.word _estack
.word reset_handler
.size vtable, .-vtable
/***********************************************************
* 'Array' declaration / initialization begins here
***********************************************************/
.type myarray, %object
myarray:
.word 0x11111111
.word 0x22222222
.word 0x33333333
.size myarray, .-myarray
/***********************************************************
* 'Array' declaration / initialization ends here
***********************************************************/
.equ myarraysize, 5 //the number of 'elements' in the 'array'.
.type reset_handler, %function
reset_handler:
LDR r0, =_estack
MOV sp, r0
/******************************************************************
* START - code example using array
/*****************************************************************/
LDR R1,=myarray // this loads the location value itself (the 1st address),
MOV R2,#0 // R2 will keep a count to make sure we don't walk off
// end of array.
LDR R3,=myarrsize // R3 will be the equivalent of 'myarrsize'.
// R0 will hold our data (pretends we're using data).
main_loop:
LDR R0,[R1] // Load the data pointed to by R1 ('myarray') into R0.
CMP R2,R3 // Are we at limit of array?
BEQ main_loop // If we are, we're done, so we'll just loop forever.
ADD R2,#1 // Not done, keep going, keep count.
ADD R1,#4 // Add 4 to register R1, so it points correctly to next
// address..
B main_loop // Loop back.
/******************************************************************
* END - code example using array
/*****************************************************************/
.size reset_handler, .-reset_handler
Upvotes: 0