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.

  • You can do:

    var1 DCD 0x00
    var2 DCD 0x00
    
      LDR R0,=var1    ; Address of var1
      LDR R1,[R0]     ; read var1 in to R1
      LDR R0,=var2    ; base address of MyAsmVar
      LDR R2,[R0]     ; Address of var2
    

  • Thanks for your answer.

    Are there short method?

    How I can write at the single line

    like this LDR R1,[R0,#var1] ; Address of var1

  • IF you want programmer convenience, then use a High-Level Language.

  • You could of course write a simple macro.

  • @Andrew

    Dont wory I use also C.

    @IB

    var1 DCD 0x00 ; Address 0x20000000
    var2 DCB 0x00 ; Address 0x20000004
    var3 DCD 0x00 ; Address 0x20000006

    var1_ EQU 0x00
    var2_ EQU 0x04
    var3_ EQU 0x06

    LDR R0,=0x20000000 ; Ram Base Address
    LDR R1,[R0,#var1_]
    LDR R2,[R0,#var2_]
    LDR R3,[R0,#var3_]

    you see need only 4 line.

    This solves my problem but not good idea.
    Because we must find (count) the values of var1_,var2_,var3_.

    Other way (you said)

    LDR R0,=var1
    LDR R1,[R0]
    LDR R0,=var2
    LDR R2,[R0]
    LDR R0,=var3
    LDR R3,[R0]

    need 9 lines. Because LDR R0,=var1 pseudo code.

    LDR R0,=var1 (LDR R0,[PC+adr1])
    LDR R0,=var2 (LDR R0,[PC+adr2])
    LDR R0,=var3 (LDR R0,[PC+adr3])

    adr1 0x20000000
    adr2 0x20000004
    adr3 0x20000006

    8086, 8051, PIC ... assembler compiler easyly solves this problem. Why i cant do by keil i dont know.

    For example for x86

    var1 dw 0
    var2 db 0
    var3 db 0

    mov ax,var1
    mov bh,var2
    mov bl,var3

  • "Why i cant do by keil i dont know."

    The differences you note are due to the processors having different architectures.

    "8086, 8051, PIC ... assembler compiler easyly solves this problem."

    What problem do you think you have? speed? code size? complexity?

    It might be worth you reading about some of the design philosophy that lies behind the ARM core.

  • You ask to me "What problem do you think you have? speed? code size? complexity?"

    Speed and Code Size importand for me. Complexity no problem.

  • The whole point of Assembler is that it has a direct 1:1 correspondence to machine instructions.

    The Assembler doesn't "solve" anything - it simply gives you direct access to the processor's instruction set - nothing added, nothing taken away.
    It leaves you to do all the "solving" using those instructions.

    The assembler cannot invent instructions that are not present in the hardware instruction set.

  • What makes you think that you can beat the compiler at this?

  • Okey i am writing again.

    var1 and var2 are 32 bit variables.
    I can easly learn the values of this variables if i know the var1 and var2 address.

    for example

    var1 variable's address is 0x20000000.
    var2 variable's address is 0x20000004.

    Base_Addr=0x20000000

    var1 relative address is 0
    var2 relative address is 4

    LDR R0,=0x20000000
    LDR R1,[R0,#0]
    LDR R2,[R0,#4]

    or

    i can define

    val1 equ 0x00
    val2 equ 0x04

    and after

    LDR R0,=0x20000000
    LDR R1,[R0,#val1]
    LDR R2,[R0,#val2]

    Ok?

    These are not problem.

    if i dont know the var1 and var2 address what can i do?

    Base address is 0x20000000

    varx dcb 0x00
    vary dcb 0x00
    ...
    ...
    ...
    var1 dcd 0x00
    var2 dcd 0x00

    LDR R0,=0x20000000
    LDR R1,[R0,#val1]
    LDR R2,[R0,#val2]

    Compiler give error message for #var1 and #var2

    Ok i may be wrong write it. There for compiler give error messages.

    what is the true form? (You say it)

    I need simple directive name but i dont know it.

    For example you say to me "use LDR R1,[R0,#AdrOf(val1)]"

    Thats all....

  • "what is the true form? (You say it)"

    There is no one true form. I have already given you a workable alternative.

    If code size is important, then you might well be better off looking at the thumb instruction set.

    If you REALLY want to do it your way then you could have a series of equates, something like:

    
    .
    .
    .
    
    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]
    
    

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

  • Ok i am giving simple C example.

    int a,b,c;

    int main()
    { a=1; b=2; c=3;
    }

    Select optimization level 0 and compile it.

    You will see following asm codes in the debug menu.

    5: a=1;
    0x000001C8 2001 MOVS r0,#0x01
    0x000001CA 4905 LDR r1,[pc,#20] ; @0x000001E0
    0x000001CC 6008 STR r0,[r1,#0x00] 6: b=2;
    0x000001CE 2002 MOVS r0,#0x02
    0x000001D0 4904 LDR r1,[pc,#16] ; @0x000001E4
    0x000001D2 6008 STR r0,[r1,#0x00] 7: c=3;
    0x000001D4 2003 MOVS r0,#0x03
    0x000001D6 4904 LDR r1,[pc,#16] ; @0x000001E8
    0x000001D8 6008 STR r0,[r1,#0x00]

    This code same as your suggested codes.

    ------------------------------------------------

    Now select optimization level 3 and recompile it.

    You will see following asm codes in the debug menu.

    5: a=1;
    0x000001C8 4804 LDR r0,[pc,#16] ; @0x000001DC
    0x000001CA 2101 MOVS r1,#0x01 6: b=2;
    0x000001CC 6001 STR r1,[r0,#0x00]
    0x000001CE 2102 MOVS r1,#0x02 7: c=3;
    0x000001D0 6041 STR r1,[r0,#0x04]
    0x000001D2 2103 MOVS r1,#0x03 8: }
    0x000001D4 6081 STR r1,[r0,#0x08]

    This codes same as my need codes.

    You see C compiler solve this problem. But we can't do by assembler.

    How I can do?

  • Of course you can - and you also got one example how to do it.

    The difference between assembler and C is that with assembler, you have to do all the extra work that the compiler does on its own.

    It's up to you to declare three individual variables, or to just allocate storage large enough for three variables and then play with the individual offsets. Or to try to do the IB Shy workaround, writing extra assembler lines to compute the offsets.

  • Other cpu's compilers has $ or offset type asm directives. But i didnt find in the keil.

    I can't solve this problem If i don't find the address learning directives.