I am currently working with the TC275 tricore chip, and am exploring the startup code taken from the example on Hightec free tricore entry toolchain. I'm wondering about the effect of square brackets in assembly statements. As I worked with ARM core before, when square brackets are surrounded by a register, it means a reference to the value that the address of that register is storing.
But for Tricore, for example with LEA instruction: "lea %a14, [%a14]lo:__crt0_config
". This instruction means something like taking the low 16 bit value of the __crt0_config
function address plus the low 16 bit value available in register a14 and then assigning it to the low 16 bit in register a14.
I refer to the documentation in the userguide of Hightec free tricore entry toolchain and it says:
Indirection: If an operand (register or constant) is used to access memory indirectly, you may, at your option, wrap it in square brackets (e.g. [r4]
). This is completely in compliance with the specification mentioned above; however, there are no options which let you specify if the use of such indirection specifiers (read: square brackets) is illegal, optional, or mandatory. This means you can’t change the default, which is ”optional”. Of course, if you use indirection specifiers at places where they’re not allowed, you’ll get an error message, which again is compliant with the Assembler Mnemonics Specification.
In addition to the lea instruction, there are also ld.w
and st.w
instruction that also use square brackets (but the mov
command does not). I think this is related to addressing mode.
Please help me understand the problem.
Thanks!!!
I'm wondering about the effect of square brackets in assembly statements. As I worked with ARM core before, when square brackets are surrounded by a register, it means a reference to the value that the address of that register is storing.
That's the same for TriCore
However, in ARM assembly language you would write [R4, #1234]
, in TriCore assembly language you would write [R4]1234
.
So on an ARM CPU, you would write [R4, #lo:__crt0_config]
instead of [R4]lo:__crt0_config
.
Specifying a constant using lo:xxx
is a feature of the tool chain, not of the CPU.
As far as I know, lo:xxx
is the low 10 (not 16) bits of the address of the symbol (__crt0_config
), sign-extended (this means: interpreted as signed 10-bit number).
And: TriCore does not have general-purpose registers (R0
-R12
), but it has registers only intended for data (D0
-D15
) and registers only intended for addresses (A0
-A15
).
In addition to the lea instruction, there are also ld.w and st.w instruction that also use square brackets (but the mov command does not). I think this is related to addressing mode.
Just like in ARM assembler, the brackets are used for memory addresses:
In ARM assembler, you write LDR R4, [R5]
but you don't write MOV R4, [R5]
.
The LEA
instruction (which also exists on x86 CPUs) is some "special case":
It takes a memory address as second argument and you can pass any valid memory addressing mode:
If the ARM CPU supported LEA
, LEA R0, [R1]
would be equal to MOV R0, R1
.
However, for the second operand, you would have the same options as for the LDR
instruction, so you could use LEA R0, [R1, #4]!
or LEA R0, [R1], #4
.
The LEA
instruction is often used to do some "complex" calculations. In your case, it is simply mis-used instead of ADD
because there is no ADD
instruction that can add 10 bits to an address register.
I refer to the documentation in the userguide of Hightec ...
Did you also have a look at Infineon's official instruction set specification?