Question

#define SVC_ARG2(call, arg1, arg2)  ({ \
uint32_t ret = 0;   \
asm volatile ("mov  r0, %[ar1]  \n"  \
              "mov  r1, %[ar2]  \n"  \
              "svc  %[code]  \n"    \
              "mov  %[ret], r0  \n" \
              :[ret] "+r" (ret)     \
              :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \
              :"r0", "r1");               \
ret;    \
})

I can not understand

              "mov  %[ret], r0  \n" \
              :[ret] "+r" (ret)     \
              :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \
              :"r0", "r1");         

this part of the code. Especially : [ret] "+r" (ret) \

Was it helpful?

Solution

This is gcc inline assembler syntax. The last 3 lines list outputs, inputs and clobbers, respectively. For output and input, the part in the square brackets is a symbolic name you can use to refer to the particular argument inside the asm block. The part in quotes is the constraint that tells the compiler what kind of argument it is: r means register, I means immediate. A + modifier normally tells the compiler that the argument is read-write, so I don't see much point in specifying that for the return value. Finally the part in the round parentheses is the value of the argument. Thus [ret] "+r" (ret) defines an output argument named [ret] which will be in a register and should be assigned to the variable ret.

OTHER TIPS

#define SVC_ARG2(call, arg1, arg2)  ({ \

Define this macro "function".

uint32_t ret = 0;   \

set ret = 0, so it exists in out stack.

asm volatile ("mov  r0, %[ar1]  \n"  \

mov ar1 into register 0

          "mov  r1, %[ar2]  \n"  \

Move register 1 into

          "svc  %[code]  \n"    \

Supervisor Call passed Call.

          "mov  %[ret], r0  \n" \

Move the contents of r0 into %[ret] (which we see later is the ret int defined just above the asm call.

          :[ret] "+r" (ret)     \

The %[ret] is a general purpose register containing the value of ret, and ret is being passed in as an in/out value.

          :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \

[code] expands to piece of code, which is passed into function as call taking two arguments that general purpose registers which we passing ar1 (holding arg1), and ar2 (holding arg2) as in parameters.

          :"r0", "r1");               \

And register 0 and register 1

ret;    \

"Return" ret

})

Close the define.

The "r" means general purpose register The "+" means in/out variable (sorta like pass by reference) The "I" is machine specific, but given the context looks to be a callable piece of code that returns a int.

The are strung together in the format: :[thing_to_replace] "how to pass things" (thing_to_pass)

Sorta like the old printf replacements, or replacements in sql prepared statements.

http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

The code loads arg1 into r0, arg2 into r1, then invokes "svc call" where call is the SVC number. It then moves the value of register r0 (which will have been set due to the svc instruction) into the C variable ret.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top