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/
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
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
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
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
> 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