Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

pls explain strcpy() assembly

468 views
Skip to first unread message

Rajaram Suryanarayanan

unread,
Jan 18, 2006, 2:51:06 AM1/18/06
to
Hi,

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;
}

Thanks,
Rajaram.


Yahoo! Photos – Showcase holiday pictures in hardcover
Photo Books. You design it and we’ll bind it!

Ashwin Rao

unread,
Jan 18, 2006, 3:26:03 AM1/18/06
to
On 1/18/06, Rajaram Suryanarayanan <rajara...@yahoo.com> wrote:
> Hi,
>
> 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.
>
>

These links might help you

http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Regards,
Ashwin

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


Vijay Subramanian

unread,
Jan 18, 2006, 3:45:51 AM1/18/06
to
On 18/01/06, Rajaram Suryanarayanan <rajara...@yahoo.com> wrote:
> Hi,
>
> 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;
> }

The esi (source index register) is referenced as S. It is set to point
to what src is pointing to. The "0" in front of src means look at the
previous list (set of output operands) and use the 0th element.
Similarly, dest references D which is the
(destination index register).

"1:\tlodsb\n\t"
1 is a label. lodsb loads a byte from what esi points to and
increments esi. The byte should be in al register.

stosb\n\t
stosb moves the byte in al into the location pointed to by edi (D).
edi will also be incremented .

testb %%al,%%al\n\t
To test for end of string test the byte in al register. If it is not
null jump back to the
top of the loop and repeat.
This will continue till you hit the end of the string (NUL) in which
case the jump will not take place. At this point the string has been
copied.

I am not sure why we need d0, d1 and d2. Can anyone give a hint? Thanks.

The syntax will make sense if you read this
http://www-128.ibm.com/developerworks/linux/library/l-ia.html

Hope this helps.
vijay

pradeep sawlani

unread,
Jan 18, 2006, 4:45:29 AM1/18/06
to
---------- Forwarded message ----------
From: pradeep sawlani <pra...@gmail.com>
Date: Jan 18, 2006 3:15 PM
Subject: Re: pls explain strcpy() assembly
To: Vijay Subramanian <subraman...@gmail.com>

I think d0,d1,d2 are output variables they will contain values of
esi,edi and al registers. I dun why we require them.
Regards
Pradeep

Momchil Velikov

unread,
Jan 18, 2006, 4:50:24 AM1/18/06
to
Vijay Subramanian wrote:
> On 18/01/06, Rajaram Suryanarayanan <rajara...@yahoo.com> 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

pankaj chauhan

unread,
Jan 18, 2006, 6:09:39 AM1/18/06
to
if i do'nt specify output operands in strcpy, will it
make any differnce,

following code works fine on my x86 machine:

inline void nstrcpy(char *src, char *dst){



__asm__ __volatile__ ( "1: lodsb \n\t"
"stosb\n\n"
"testb %%al, %%al \n\t"
"jne 1b"
:
: "S"(src) , "D" (dst)
);



}

please let me know if above code has some problem

Thanx
PC


Vision without action is merely a dream, action without vision is wastage of time, vision and action together can change the world ....

Send instant messages to your online friends http://in.messenger.yahoo.com

Momchil Velikov

unread,
Jan 18, 2006, 7:55:26 AM1/18/06
to
pankaj chauhan wrote:
> if i do'nt specify output operands in strcpy, will it
> make any differnce,
[please, do not top post]

> following code works fine on my x86 machine:
>
> inline void nstrcpy(char *src, char *dst){
>
>
>
> __asm__ __volatile__ ( "1: lodsb \n\t"
> "stosb\n\n"
> "testb %%al, %%al \n\t"
> "jne 1b"
> :
> : "S"(src) , "D" (dst)
> );

This is not correct, because it lies to the compiler that the insn does not
modify anything the compiler cares about. If ``src'' and ``dst'' were already
allocated in ESI and EDI, after the insn is executed, their value is changed,
but the compiler knows nothing about it. Likewise for EAX.


See the following test case:

static inline void
nstrcpy (char *dst, const char *src)


{
__asm__ __volatile__ ("1: lodsb \n"

" stosb \n"
" testb %%al,%%al \n"
" jne 1b"
:
: "S" (src), "D" (dst));
}

void
foo (unsigned int n, const char **s, char **da, char **db)
{
while (n--)
{
nstrcpy (da [n], s [n]);
nstrcpy (db [n], s [n]);
}
}


The loop in ``foo'' is compiled to:

.L4:
movl (%ecx), %esi ;; loading s[n]
movl (%edx), %edi ;; loading da [n]
#APP ;; inlined nstrcpy
1: lodsb
stosb
testb %al,%al
jne 1b
#NO_APP
;; OOPS %eax should contain the &db [n], but %eax is already modified

movl (%eax), %edi ;; loading db [n]
;; or so we thought, in fact it starts nethack

;; OOPS, FAILED TO RELOAD s[n], because it is already in %esi and the compiler
;; does not know %esi changed
#APP
;; this nukes Iran
1: lodsb
stosb
testb %al,%al
jne 1b
#NO_APP
incl %ebx
subl $4, %ecx
subl $4, %edx
subl $4, %eax
cmpl %ebx, %ebp
jne .L4

~velco

0 new messages