In retrospect, having ONLY the 16bit instructions in CM0 is ... really annoying, especially for the assembly language programmer.Why did ARM create a 16 bit version of their normal 32 bit instructions?
As you've noticed, it results in unexpected limits on the size of immediate operands (and none of the fancy shifted immediate operands you get with the 32bit instructions), only "some" syntax ("lsls" vs "lsl"), and it ends up not having the sort of regular structure that one normally expects from a RISC architecture. Image may be NSFW.
Clik here to view.

I don't know that I'd pick a Pico as a target for a beginning ASM class; in addition to the CM0+ oddities, there are also the build complications (needing a secondary bootloader... (perhaps you can avoid that my loading via SWD to RAM.))
Meh. Most architectures with "flags" will have most ALU instructions set them, or an option to do so. You'll note that on CM0+ you only have "ANDS", which makes it explicit (and no immediate-value version of AND, either.) CMP has limits on immediate values as well (fortunately, that includes 0!)AND the RESET_DONE value with the bitmask.
CMP the result with 0
BEQ back to reset
Yes, and that's what I would tend to do no matter what the architecture and ISA. It means you only need to remember that CMP sets flags, don't have to care about or know what any other operations do, whether they set flags or don't, require an 's' suffix or something else to set those flags.
Use something like an AVR and there is a nice table of which flags are set by which instructions (for instance, AND will not affect the carry.)
If you're programming in ASM, you might as well be efficient!
(Note that several newer architectures (MIPS, RISC-V) DON'T have flags (apparently they're difficult to pipeline))
I would normally use something like:I am currently using:arm-none-eabi-as blink.s -o blink.o
arm-none-eabi-gcc -c -mcpu=cortex-mzeroplus -mthumb blink.S -o blink.o
Using the "gcc" front end will run the C preprocessor over files with the .S (capitalized) extension
I'm not entirely sure whether the -mcpu does more than your ".cpu" directive, but it might...
Simpler solution: use the same "literal value" syntax of LDR that you used to load up the address:stick 1 in r1 and shift left 25 spaces to get 00000001000000000000000000000000
Code:
ldr r0, =0x4000f000 ldr r1, =(1<<25) ; or whatever. str r1, [r0]
About a decade ago (!) there was some interesting discussion on very minimal programming of ST ARM chips.
I wrote up some examples that you can find (with references worth following) here: https://github.com/WestfW/Minimal-ARM
(But that was on a CM3 chip, which has fewer limitations, and it had a "normal" memory structure.)
Statistics: Posted by WestfW — Sat Jul 06, 2024 2:54 am