delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/03/26/12:46:29

From: buers AT gmx DOT de (Dieter Buerssner)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: I'm Back...
Date: 26 Mar 2000 16:05:41 GMT
Lines: 100
Message-ID: <8blcgk$57f8t$1@fu-berlin.de>
References: <38DBF7AF DOT A0786922 AT ou DOT edu> <38DC04C8 DOT 72C075C6 AT bigfoot DOT com> <38DC1398 DOT E1B15F0B AT ou DOT edu> <8bi4je$51gdn$2 AT fu-berlin DOT de> <38DCF570 DOT 4DD62F2A AT ou DOT edu>
NNTP-Posting-Host: pec-62-216.tnt2.me.uunet.de (149.225.62.216)
Mime-Version: 1.0
X-Trace: fu-berlin.de 954086741 5487901 149.225.62.216 (16 [17104])
X-Posting-Agent: Hamster/1.3.13.0
User-Agent: Xnews/03.02.04
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019