TIP: Click on subject to list as thread! ANSI
echo: public_domain
to: Frank Malcolm
from: Paul Edwards
date: 1996-01-09 19:04:18
subject: movsb

PE> PE> HOWEVER, what could be done is if I give you the maximum length
PE> PE> as WELL as just the '\n' terminator, then it could be written
PE> PE> just as fast.

PE> On the assumption that you are only concerned about not overrunning
PE> the buffer, but besides that, you don't mind copying an extra
PE> byte or three.

FM> Yes, I guess for total safety you should specify the routine as copying
FM> up to and including any \n, or the supplied maximum output buffer size,
FM> whichever comes first.

No, that's not what I'm talking about.  I can guarantee the '\n'.
What I'm talking about is making the main loop copy up to 4 less
than the size specified in the destination buffer, so that there
is no speed penalty, and then copying the final characters using
a more inefficient method.

PE> However, on closer reading of the ISO standard, I cannot see

FM> Oh, this is an implementation of an ISO-specified routine? I didn't
FM> realise that.

fgets() is an ISO routine.  My implementation of it puts the
critical section into the single line of code I posted 
originally.

PE> anything that would allow me to do that.  It says that characters
PE> stop getting read when the newline character is read.  What I
PE> would have LIKED them to have said is "The contents of the
PE> array after the newline character will be indeterminant".  But

FM> True, but if its an ISO standard function you'd have to allow for a user
FM> who knew that his input line would never exceed say 41 bytes, and
FM> provided an output buffer of exactly that size. You'd clobber the
FM> subsequent.

I'm not sure what you're talking about here.  There is no way my
original one-line code can clobber the user's buffer.  It's
deliberately set up that way, with a sentinel stopping any clobbering.
What I am talking about is wringing the maximum possible from the
inner loop.

PE> as it stands at the moment, people can instead be sure that their
PE> array will not be clobbered with extra bytes, which means that
PE> they can play silly buggers, and, e.g. do an fgets() and get
PE> a line of BBBBBBBBBBBBBBBBBBBB and then an fgets and get a line
PE> of AAAAAAA, and then clobber the '\n' with a C, knowing that
PE> they will now get a AAAAAACBBBBBBBBBBBB, e.g.

FM> Yeah, users do strange things. :-)

No, that's the only problem.  The inner loop could be made 
perfectly fast, IF the user was happy to get the last bit of his
buffer clobbered.  Note no buffer overrun.  However, the ISO
standard allows them to assume that what was in their buffer
before calling fgets, will still be there, the characters
after the newline anyway.

PE> What this means is that two halfword *stores* instead of a single
PE> fullword store is unavoidable in the main loop.

FM> Yes it is, in the *main* loop. You'd modify my Test 10 to do all those
FM> tests before the "mov [di],eax" and handle the special
cases of 1, 2 or
FM> 3 bytes as special cases after the main loop.

Yes it is unavoidable?  To do the tests, you need to do a shift,
a shift which will destroy the register you were planning on using
to use when storing to the destination buffer.  The best you can
do is two halfword stores instead of one dword store.

PE> That also means that there is no use in having the length available.

FM> I'd still prefer to have such a routine specified as I suggested above,
FM> but then I'm a programmer who believes in protecting users from
FM> themselves. :-)

There's no user involved.  BFN.  Paul.
@EOT:

---
* Origin: X (3:711/934.9)

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.