Re: pls explain strcpy() assembly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Vijay Subramanian wrote:
> On 18/01/06, Rajaram Suryanarayanan <rajaram_linux@xxxxxxxxx> wrote:
>> Can anybody pls explain me step by step what is done by the assembly code
>>below ? Particularly, I want to know how "src" and "dest" get substituted in
>>the assembly code.
>>
>>  static inline char * strcpy(char * dest,const char *src)
>> {
>> int d0, d1, d2;
>> __asm__ __volatile__(
>>         "1:\tlodsb\n\t"
>>         "stosb\n\t"
>>         "testb %%al,%%al\n\t"
>>         "jne 1b"
>>         : "=&S" (d0), "=&D" (d1), "=&a" (d2)
>>         :"0" (src),"1" (dest) : "memory");
>> return dest;
>> }
> I am not sure why we need d0, d1 and d2. Can anyone give a hint? Thanks.

The insn takes an input esi and edi and produces output in (i.e. modifies) esi,
edi, eax and memory.

Thus we have to specify that inputs must be copied to esi and edi

  : <outputs>
  : "S" (src), "D" (dst)
  : <clobbers>

then specify that the insn modifies ESI and EDI

  : "=S" (<var>), "=D (<var>)"
  : "S" (src), "D" (dst)
  : <clobbers>

but this is invalid, because it tells GCC to allocate two registers from the
each of S and D classes, but both contain a single register, moreover the insn
in fact modifies its inputs, hence we must tell that corresponding inputs and
outputs are in fact in the same register [1]:

  : "=S" (<var>), "=D" (<var>)
  : "0" (src), "1" (dst)
  : <clobbers>

Now we have to tell where the outputs to go. As we are not really interested in
the values of the ESI and EDI, we can specify arbitrary temporary variables.
Note that we can't use the variables ``src'' and ``dest'' we already have [2],
because the compiler will copy ESI and EDI to them and we do not want it for
```dest''. Thus:

  : "=S" (tmp0), "=D" (tmp1)
  : "0" (src), "1" (dst)
  : <clobbers>

and finally

  : "=S" (tmp0), "=D" (tmp1), "=a" (tmp2)
  : "0" (src), "1" (dst)
  : "memory"

Note that in this particular case there's no need for the ``&'' constraint.  It
prevents the same register from being allocated both for input and an output
operand, but in this case we explictly assign concrete registers, so this cannot
happen.

~velco

[1] Note that this could theoretically expressed also as:

  : "=2" (<var>), "=3" (<var>)
  : "S" (src), "S" (dst)
  : <clobbers>

but this is INVALID as gcc allows number constraints only on input operands.

[2] well, we can use ``src'', because it is dead after the insn

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux