We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, i have just got a cortex-m0(LPC1114) based dev board. I'm reading about the architecture and instructions. My understanding is that it supports most thumb 16-bit instructions and a handful thumb-2 32-bit instructions. If the processor has a 32-bit bus which instructions are fetched(im assuming this, also i have limited knowledge of a CPU's inner workings), why don't it support more thumb-2 instructions? It seems like a waste, or maybe it fetches two 16-bit instructions?
My other issue is related to to my first question. I'm trying to set the core registers with immediate values using MOV. I read that you can use MOV for the for the 16 lower bits, and MOVT for the 16 higher bit(this is only for cores which supports ARM32 i suppose). However first it seems MOVT is not supported by cortex-m0, in arm-none-eabi-as: "Error: selected processor does not support Thumb mode `movt r0 , r1'. Also when i read the ARMv6-M reference manual, i read that MOV can only set a immediate value up to 8-bits long. This all seems very strange to me. I got a hint on a IRC that your really supposed to use PC relative addressing to set registers "directly", which i haven't read much into. Are there no efficient way to set immediate 32-bit values for registers, using MOV or other data instructions?
Thanks for responses!
Hi ei24 and welcome to the community!
As Yasuhikok explained, the Cortex-M0 only supports 16-bit instructions, no 32-bit instructions are supported
That means that the MOVT instruction does not exist for the Cortex-M0.
A different way of loading a 32-bit constant into a register from the literal pool, is to use the LDR rT,=imm pseudo instruction.
This pseudo-instruction automatically puts the immediate value in the literal pool, and creates a LDR instruction that fetches it.
You should make sure that your literal pool is close by, since the Cortex-M0's addressing range for the LDR instruction is quite limited.
That means right after a b or bx (branch) instruction, you should place the keyword '.pool' (when using the GNU assembler).
I do not know the keyword which is used in other assemblers, though, it might be the same, but without a dot prefix.
At the ARM Information Center, you may find the Cortex-M0 Technical Reference Manual and the Cortex-M0 Devices Generic User Guide helpful in addition to the ARMv6-M reference (which you have already).
Some time ago I wrote an article on ARM Cortex-M0 assembly programming tips and tricks - it seems that it's now revived and has gotten quite popular again.
Thanks it seems like a nice community!
I cannot place the fetched word right before the instruction? I guess it doesn't matter either way, but i wonder.
I used .word, i read your article, maybe i will use .pool if i need to port code in the future.
The community definitely is a nice place if you ask me (I'm just a user like you). Unfortunately, we might not be able to answer all questions as there are not so many of us developers here; but of course we want to if we can.
For LPC-specific questions, you may also find the lpcware.com forum helpful; this is usually where developers who work with LPC devices hang out.
The reason that you can't place the fetched word right before the instruction is that the 16-bit instruction set is quite limited.
As far as I recall, negative offsets are not available for PC-relative addressing, thus you'll have to place them after the instruction at some point.
Since negative offsets are not available, there will be a wider range of positive offsets available, thus you can have some code between the loading and the .pool.
In some cases, you may want to have a register point permanently to an area in memory, which contains data or literals, but normally the literal pool is preferred when you need to load constant values (because it does not cause any overhead).
If you need to port the code, it might be a good idea to have an include file, which contains macros. Doing this makes it possible to 'emulate' directives from other assembers; for instance, the KEIL assembler does not use the dot prefix as far as I know, so you could write a macro called "pool", which just contains ".pool" if you're using the GNU assembler.
You may also find my article on Useful assembler directives and macros for the GNU assembler interesting.
Ill keep the LPC forum in mind
Yeah, there is no real reason why i would want to fetch a word thats placed before the LDR.
Thanks but i already bookmarked your article previously today