1
votes

Can you explain me this code ? I really don't understand it.

See http://lxr.free-electrons.com/source/arch/arm/include/asm/uaccess.h#L70

 #define __addr_ok(addr) ({ \
         unsigned long flag; \
         __asm__("cmp %2, %0; movlo %0, #0" \
                 : "=&r" (flag) \
                 : "" (current_thread_info()->addr_limit), "r" (addr) \
                 : "cc"); \
         (flag == 0); })

 /* We use 33-bit arithmetic here... */
 #define __range_ok(addr,size) ({ \
         unsigned long flag, roksum; \
         __chk_user_ptr(addr);   \
         __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
                 : "=&r" (flag), "=&r" (roksum) \
                 : "r" (addr), "Ir" (size), "" (current_thread_info()->addr_limit) \
                 : "cc"); \
         flag; })

This is from ARM Linux kernel, __range_ok

1
This guide should be helpful: ethernut.de/en/documents/arm-inline-asm.html. There's one thing I don't get here. It appears the flag operand is used, uninitialised even, and being listed as output only? - domen
Seems I was too late to edit. The "" is "0" in more recent sources, and "0" means to use in place of first register, so "%0". I think that should also answer your question to the accepted answer. See gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html for more info. - domen

1 Answers

1
votes

As a general source of info regarding the register usage and other decorations, look at the docs for GCC Extended Inline Assembly

I suggest you run this source through

gcc .... -S

to see what the resultant assmebly generated is.

You could also run

objdump -dC -S <objectfile.o>

You will need objdump from your cross-compiler toolchain. Also, compile with debug information to get source annotation (-S). Compile with -O0 to avoid confusion due to optimization.