Mail Archives: djgpp/2000/03/26/12:55:52
Thank you once again for responding. I will look this over and I will
also read over the FAQ to see what else I can learn. Once again, thank
you for your time.
-David C.
Dieter Buerssner wrote:
>
> David Cleaver wrote:
>
> >> extern __inline__ void _farpokex (unsigned short selector,
> >> unsigned long offset,
> >> void *x, int len)
> >> {
> >> __asm__ __volatile__ ("pushl %%es\n"
> >> "movw %w3, %%es\n"
> >> "rep\n"
> >> "movsb\n"
> >> "popl %%es"
> >> : "=S" (x), "=D" (offset), "=c" (len)
> >> : "r" (selector), "0" (x), "1" (offset), "2" (len));
> >> }
> >>
> >> But I wonder, whether it is allowed, to change es without
> >> wrapping it into cli/sti pairs. (An ISR may assume stanard es)
>
> >Thank you for posting your response. But, because I don't understand
> >'asm', I would like to ask several questions regarding your post:
>
> I suggest, reading the FAQ, question 18.12. The gcc manual will
> explain, how to do inline assembly with gcc. BTW. If you don't
> understand inline assembly (yet), you may want to have a look
> at the movedata function, that can do exactly the same as your _farpokex.
> And even when you understand inline assembly, movedata can be preferable in
> many situations, but it won't get inlined. However, it will be
> more efficient for large data move.
>
> >1. Why did you change "rm" (selector) to "r" (selector)?
>
> I do not know, whether "rm" is allowed, but I do know, that "r" is
> allowed, and that it should work. "r" means, put it in any general
> purpose register.
>
> >2. Do the variables have to be put into some specific order? (like it
> > seems you have done above.)
>
> Not in general, but input and output lists must be consistent,
> see below. Also, after reordering the lists you must renumber
> the 3 in "movw %w3, %%es\n", when selector is not the fourth
> register anymore. You probably noticed, that it was "movw %w0, %%es\n"
> in the original code.
>
> >3. Why wasn't an equal-sign put in front of the "rm" variable?
>
> It is input only, and it won't be changed (clobbered) by the code.
>
> >4. Why did you choose zero for x, and one for offset, and two for len,
> > and nothing for selector?
>
> X is int the first register in the output list. You refer to the first
> output register by "0", to the second by "1", etc. in the input list.
> So for x, you are saying to the compiler, overwrite x with whatever is
> ESI after the assembly. Also you tell the compiler that x should be in
> ESI (which is "0" here, AFAIK using "S" instead of "0", does not
> work), before your assembler code starts.
>
> This is the "new" (and non obvious) method, to tell the compiler,
> that the input register ESI was changed by the assembler code.
> Earlier you could put "ESI" in the clobber list, and did not
> need the output list at all for this. (This is how your original
> code worked.)
>
> Please note, that the method I described, works here only, because
> you don't need x anymore. If you would need x later, you would
> need a temporary variable.
>
> So instead of
>
> : "=S" (x), "=D" (offset), "=c" (len)
> : "r" (selector), "0" (x), "1" (offset), "2" (len));
>
> you could write
>
> {
> unsigned temp1, temp2, temp3;
> /* __asm__( ...
> : "=S" (temp1), "=D" (temp2), "=c" (temp3)
> : "r" (selector), "0" (x), "1" (offset), "2" (len));
> }
> /* can use unchanged x here */
>
> >5. I really don't know anything about cli/sti pairs (or an ISR)!
> > What do these terms mean?
>
> Cli: clear interrupt flag, sti: set interrupt flag. Code between
> cli and sti will not be interrupted (by maskable external interrupts).
> ISR: interrupt service routine.
>
> But, as I said, I have no idea whether one has to take care of the
> modified ES.
>
> So, my question to the experts is:
>
> When you temporarily change ES, and an assyncron signal will
> be raised, will the signal handler see the changed ES or the
> standard ES=DS? (Off topic, but would this be differnt under
> linux?)
- Raw text -