1

I'm using the following code to do a simple counter-based delay/wait for ARM:

.thumb_func
dowait:
   ldr r7,=0x200000
dowaitloop:
   sub r7,#1
   bne dowaitloop
   bx lr        

I got this function from dwelch's blinker01 mbed_samples, which works fine in other led-blinking-type sample programs. However the program I'm currently working on needs to have .syntax unified at the top because I'm using Thumb-2 instructions (e.g. ITTEE).

I suspect ".syntax unified" is the issue because I took the known-working blinker01 example and added .syntax unified and it no longer worked when I uploaded to my board.

While I don't have all the gdb stuff figured out yet to prove it, the function seems to not be counting / delaying.

Is there a different way to re-write this "delay" function to work with unified / Thumb-2 syntax?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Craig
  • 4,323
  • 2
  • 29
  • 32
  • Delay loops are flawed. There are bus delays, prefetching speedups, alignment slowdowns. Use a timer! – domen Nov 11 '11 at 20:03

1 Answers1

5

You need to use SUBS when you want the instruction to update the flags.

.syntax unified
.thumb_func
dowait:
   ldr r0,=0x200000
dowaitloop:
   subs r0,#1
   bne dowaitloop
   bx lr   

Another note: R7 is not a clobber register, so in the case you use the dowait function from "C" code, there will be errors as the compiler does not expect R7 to be modified. This is why I changed it to R0.

Turbo J
  • 7,563
  • 1
  • 23
  • 43
  • I'm pretty sure I tried `subs` instead of sub and it didn't make a difference. Do I *have* to use r0 instead of r7? I'm only working in asm here, not C. – Craig Nov 10 '11 at 14:25
  • Try again. This is the loop I use, needs R0 because the other code is C here. – Turbo J Nov 10 '11 at 14:35
  • Whether you can use R7 safely I cannot say as I don't see all of your code. – Turbo J Nov 10 '11 at 14:35
  • 1
    I'll give it another try, I'm using r0 elsewhere but I can probably just a different register. Also, do you have a link/reference regarding these register restrictions, r0 vs. r7, etc? I'm currently reading "The Definitive Guide to the ARM Cortex-M3 (2nd edition)" by Joseph Yiu and this is the first I've heard of these restrictions. – Craig Nov 10 '11 at 14:53
  • r0-r3 and r12 are safe to clobber. The rest must be saved and restored if modified. vFPU registers also have rules, but I don't have that handy at the moment. – Michael Dorgan Nov 10 '11 at 16:21
  • "The Definitive Guide to the ARM Cortex-M3 (2nd edition)" Chapter 10.5.1 explains this a tiny bit. Another thing to keep in mind is exception context: R7 is *not* saved/restored automagically. – Turbo J Nov 10 '11 at 20:23
  • Thanks for the clarification, also `subs` fixed my issue. – Craig Nov 11 '11 at 02:48
  • 2
    gas does not like subs when you are not using the unified syntax thus the reason I didnt have it in that code. the thumb sub instruction always computes flags where the arm sub it is an option specified by putting the s there sub => thumb, compute flags, arm dont compute flags. subs => arm compute flags. from there you have to look at what the unified assembler allows wants and it appears it wants subs. – old_timer Nov 11 '11 at 15:22
  • the code being referenced was a very simple assembly only example thus the use of r7 (something not used by the other code), to make it callable from C absolutely use r0-r3. – old_timer Nov 11 '11 at 15:24