This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Declaring Variables in cortex m3 Assembly Language

I declare 32 bit variables in the MyAsmVar section.

I know the base address of MyAsmVar. Also I know the address of var1 and var2.

AREA MyAsmVar, DATA,NOINIT, READWRITE, ALIGN=3

var1 DCD 0x00
var2 DCD 0x00

LDR R0,=0x20000000 ; base address of MyAsmVar
LDR R1,[R0,#0] ; read var1 in to R1 (var1 address is 0)
LDR R2,[R0,#4] ; read var2 in to R2 (var2 address is 4)

We must know the numeric value of variable address and this is not good.

How can I use the variables names instead of address?

I want the following lines but compiler give error messages;

LDR R0,=0x20000000
LDR R1,[R0,#var1] ; read var1 in to R1
LDR R2,[R0,#var2] ; read var1 in to R2

Also i try following lines but compiler dont compile.

LDR R1,[R0,#&var1] ; read var1 in to R1
LDR R2,[R0,#&var2] ; read var1 in to R2

if I use

var1 equ 0
var2 equ 4

problem solving, but i dont want to count address of variables.

  • "But we can't do by assembler."

    Didn't my suggested method do the same thing?

    If you really want it, you could do it. As I said before:

    "You could of course write a simple macro."

  • @IB Shy, i said "Which asm directive gives to me address of the variable, i dont know."

    Therefore i cant write the macro.

    Can you write?

  • "I can't solve this problem"

    So why don't you just write in 'C', then?!

    How long do you think it is going to take you to become sufficiently profficient at ARM Assembler for you to be able to outsmart the compiler?

    If you really need to become an expert ARM Assembly programmer - which you will need to be in order to outsmart the compiler - then I would suggest taking a training course...

  • "Which asm directive gives to me address of the variable, i dont know."

    Part of my example loaded R0 with the address of VarBase.

    Part of my example set a variable to determine the offset of a variable from a reference point.

    So, there you are. All the information you need.

    "Can you write?

    Yes, and please don't ask for an example - I've already given you the starting point for one.

  • VarBase                           ;Base address for the following variables
    
    Var1         dcb   0              ;Variable #1
    Var2         dcb   0              ;Variable #2
    
    OFFSET_VAR1  set   Var1-VarBase   ;Offset from VarBase for Var1
    OFFSET_VAR2  set   Var2-VarBase   ;Offset from VarBase for Var2
    

    .

    Is starting point this codes?

    OFFSET_VAR1 set Var1-VarBase ;Offset from VarBase for Var1

    we don't know the numeric value of address of Var1

    Therefore you cant write the this line "OFFSET_VAR1 set Var1-VarBase"

    But you can write following codes

    Var1         dcb   0              ;Variable #1
    Var2         dcb   0              ;Variable #2
    Var3         dcw   0              ;Variable #3
    Var4         dcd   0              ;Variable #4
    Var5         dcd   0              ;Variable #5
    
    and
    
    OFFSET_VAR1  equ   0
    OFFSET_VAR2  equ   1
    OFFSET_VAR3  equ   2
    OFFSET_VAR4  equ   4
    OFFSET_VAR5  equ   8
    

    .

    I dont use this lines because i dont want to count "which variable where"

  • "we don't know the numeric value of address of Var1"

    I gave you the basic idea. I've just done very little reading of the Keil documentation and confirmed that the idea is fundamentally correct. I've looked at some source code included with the Keil distribution and it does the same sort of thing.

    Sorry, but if you're wanting to be spoon fed, you had better find someone else.

  • I use 32K limitted version of Keil. (This is may be problem.)

    --- I try this ---

    LDR R1,[R0,#Var1];  Keil give error mesage:
    
    Startup.s(163): error: A1110E: Expected constant expression
    Startup.s:   163 00000100   LDR  R0,[r1,#var1]
    Startup.s:                               ^
    Startup.s: 1 Error, 0 Warnings
    

    --- I try this ---

    LDR R1,[R0,#$Var1];  Keil give error mesage:
    
    Startup.s(163): error: A1169E: Missing close square bracket
    Startup.s:   163 00000100   LDR  R0,[r1,#$var1]
    Startup.s:                               ^
    Startup.s: 1 Error, 0 Warnings
    

    --- I try this ---

    Var1         dcb   0              ;Variable #1
    
    OFFSET_VAR1  set   Var1-0x20000000   ;Offset from VarBase for Var1
    
    
                 LDR   R0,=VarBase           ;Set R0 to base address of variable block
                 LDR   R1,[R0,#OFFSET_VAR1]  ;
    
    Startup.s(66): error: A1163E: Unknown opcode set , expecting opcode or Macro
    Startup.s:    66 00000004 OFFSET_VAR1  set   var1-0x20000000
    Startup.s:                             ^
    Startup.s: 1 Error, 0 Warnings
    

    I didnt find how can i solve this problem in the Keil. (Also i tried the GBLA directive.)

    But if i cant find the answer i will write precompiler program.

    I write following asm codes

    Var1 DCD 0x00;
    Var2 DCD 0x00;
    Var3 DCD 0x00;
    Var4 DCD 0x00;

    LDR R0,=0x20000000
    LDR R1,[R0,#ADRVar1]
    LDR R2,[R0,#ADRVar2]
    LDR R3,[R0,#ADRVar3]
    LDR R4,[R0,#ADRVar4]

    Here we dont have the ADRValx values. My program automaticaly calculate the address of varaibles and inserts the following lines in to orginal asm source.

    ADRVar1 equ 0x000
    ADRVar2 equ 0x004
    ADRVar3 equ 0x008
    ADRVar4 equ 0x00C

    Now Keil easyly compiles my codes.

    But i think i do not know to small trick. Because this basic problem must be solve by keil asm compiler.

  • MDK-ARM Evaluation Tools

    Programs that generate more than 32 Kbytes of code and data will not compile, assemble, or link.

    The debugger supports programs that are 32 Kbytes or smaller.
    The compiler does not generate a disassembly listing of the machine code generated. The -S, --asm, and --interleave compiler command-line options are disabled.

    The compiler and assembler do not generate position-independent code or data. The --apcs /ropi /rwpi /pic/ pid compiler and assembler command line options are disabled.

    The assembler and linker create Symbolic Output Format objects which cannot be linked with third-party linker utilities. Fully licensed tools generate standard ELF/DWARF files which may be used with third-party utilities.

    The linker does not accept scatter-loading description files for sophisticated memory layouts. The --scatter command line option is disabled.

    The base address for the code and constants in memory must be 0x000080000, 0x000100000, 0x000200000, 0x000300000, 0x000400000, 0x010400000, 0xXX000000, or 0xXX800000 (where XX is a Hexadecimal number from 00-FF). When the base address is 0x0 the linker places the code at the start of on-chip Flash of most ARM processor-based microcontrollers.

    Is the my problem is linked to text bold? (I use uvision V1.14.4)

  • "I use 32K limitted version of Keil. (This is may be problem.)"

    Not the problem.

    "Is the my problem is linked to text bold? (I use uvision V1.14.4)."

    Not the problem.

    Why do you try to find a very complicated reason? It's not complicated.

    Sorry, but I think I have already given you something very close to the answer already and I'm not going to give any more. If you can't find the solution for such a simple problem yourself, maybe you should consider just doing whatever you're trying to do in C.

  • Absolutely!

    Again, to outperform the compiler will require you to be very good at ARM Assembler. That is clearly not the case, so you have to choices:

    1. spend some serious time doing some serious study of ARM assembler;

    2. let the compiler to it.

    If you really want to go for option 1, then I would recommend a taught class; but, at least, you will need some books: http://www.keil.com/books/armbooks.asp

  • Thank you for your efforts. But unsolved problem is continue.

    @Andrew Neil, what is my question? What do you say?
    I know the assembler and C. But I'm new to cortex m3 assemby.

    Please dont give me any answer. I ask to other persons.

    Var1 DCD 0x0
    Var2 DCD 0x0
    Var3 DCD 0x0

    Var1, Var2 and Var3 are defined in the ram.

    I want to read this variables using assembly language.

    Following 4 line (12 byte) codes written for this purpose.

    LDR  R0,=Var    ;(2 byte)
    LDR  R1,[R0,#0] ;(2 byte) Read Var1 in to R1
    LDR  R2,[R0,#4] ;(2 byte) Read Var1 in to R2
    LDR  R3,[R0,#8] ;(2 byte) Read Var1 in to R3
    ....
    ....
    Var1_Base_Address ; 4 byte written automaticaly by the keil
    

    I dont like to see #0, #4 and #8 values. I preffer the see variable name.

    Following 6 line codes too understable but need 24 byte.

    LDR  R0,=Var1 (2 byte)
    LDR  R1,[R0]  (2 byte)
    LDR  R0,=Var2 (2 byte)
    LDR  R2,[R0]  (2 byte)
    LDR  R0,=Var3 (2 byte)
    LDR  R3,[R0]  (2 byte)
    
    Var1_Base_Address 4 byte written automaticaly by the keil
    Var2_Base_Address 4 byte written automaticaly by the keil
    Var3_Base_Address 4 byte written automaticaly by the keil
    
    

    As you seen second program longer then first program. (24-12=12 byte longer)

    Let look to first program again.

    LDR  R0,=Var    ;(2 byte)
    LDR  R1,[R0,#0] ;(2 byte)
    LDR  R2,[R0,#4] ;(2 byte)
    LDR  R3,[R0,#8] ;(2 byte)
    ....
    ....
    Var1_Base_Address 4 byte
    

    i will change this program

    LDR  R0,=Var    ;(2 byte)
    LDR  R1,[R0,#Var1_] ;(2 byte)
    LDR  R2,[R0,#Var2_] ;(2 byte)
    LDR  R3,[R0,#Var3_] ;(2 byte)
    ....
    ....
    Var1_Base_Address 4 byte
    

    Var1_ equ 0
    Var2_ equ Offset_Of_Var2
    Var3_ equ Offset_Of_Var3

    Offset_Of_Var2 = Physical Address of Var2 - Physical Address of Var1
    Offset_Of_Var3 = Physical Address of Var3 - Physical Address of Var1

    But How do I write this i dont know.

    Problem only and only this. Because i dont know "what is the address or offset operator in the keil?"

  • Why do you keep repeating the same question?

    I have already indicated how you can do it.

    I have even told you where you can find examples. Did you look?

    Now I'll repeat something:

    If you can't find the solution for such a simple problem yourself, maybe you should consider just doing whatever you're trying to do in C.

  • There is no such thing as the assembler - each assembler is specific to its target instruction set!

    "I'm new to cortex m3 assemby"

    So you're not going to outsmart a Cortex-M3 compiler, then!

    So, Again: why not just do this in 'C' ?

  • @IB Shy

    Do you say your following answer?

    .
    .
    
    VarBase                           ;Base address for the following variables
    
    Var1         dcb   0              ;Variable #1
    Var2         dcb   0              ;Variable #2
    
    OFFSET_VAR1  set   Var1-VarBase   ;Offset from VarBase for Var1
    OFFSET_VAR2  set   Var2-VarBase   ;Offset from VarBase for Var2
    
    .
    .
    .
    
                 LDR   R0,=VarBase           ;Set R0 to base address of variable block
                 LDR   R1,[R0,#OFFSET_VAR1]  ;
                 LDR   R2,[R0,#OFFSET_VAR2]
    
    
    
    
    Did you compile it?  (Compiler give error)
    
    My compiler limited version and not produce the lst files of C program.
    Therefore C program how introduce this problem i can not look.
    
    
    

  • "Did you compile it? (Compiler give error)"

    No I did not! And I would assemble something like this, I would not compile it.

    Did you read what I said when I posted that code?

    WARNING: This code block is intended to illustrate a possible method. It is not complete and may have syntax errors.

    I also was careful to say that I had indicated what you had to do.

    Your responses show me that you are not taking the information given and following it through, so I think it would be wrong for me to just tell you.

    It is not a complex problem.

    It looks like Andy is right when he says:

    "So you're not going to outsmart a Cortex-M3 compiler, then!"