Re: Embedding assembler in a language
- From: tm <thomas.mertes@xxxxxx>
- Date: Thu, 19 Nov 2009 08:30:48 -0800 (PST)
On 19 Nov., 15:21, Marco van de Voort <mar...@xxxxxxxx> wrote:
On 2009-11-19, tm <thomas.mer...@xxxxxx> wrote:
As any tool, it can be abused. Just like people can use Duff's device to
manually unroll loops in C. You will also find that on the net.
Premature optimization is premature optimization, in HLL or assembler. But
it is not a reason to ban all tools or constructs that could be abused for
Ok. But one line of assembler makes a program unportable.
So makes one pointer to int cast.
I know of "pointer to int casts" which don't make a program
unportable. In general I don't encourage any unportable programming
IIRC UCSD Pascal supported assembler functions/procedures to
compensate for the slow interpretation of p-code
Ok, maybe I should have said "in this century".
Providing some support for assembler (or C) is a common strategy to
improve the performance of interpreted languages. I don't want to accuse
languages or implementations. I just want to point out that inline
assembler is also used for performance reasons and that some effort could
be used to improve the performance of the main language instead.
That is probably not possible, since that would mean dragging the HLL down.
Usually such lowlevel use is limited to a few lowlevel modules.
That is more or less the runtime library argument I already mentioned.
Well, the runtime library could provide a portable support for some
Also it is a bit unfair to point to TP code for your point. It on average
two decades old and frozen code.
Actually it is not TP code it is assembler which pretends to be
Pascal. If it would be real (portable) Pascal code it would be
usable today without problems. This is also the reason why I see
portable code as much more valuable than unportable code.
(probably not, the avg TP code is stuffed top till bottom with dosism and
Dosism and 16-bitisms are another example of how to write unportable
programs. Todays programs use Windowsisms and Linuxisms instead.
Sadly operating system dependend functions are often preferred over
operating system independend functions.
But IMHO you simply refuse to acknowledge that their might have been a
reason then to do this.
No, No I believe that there is often a reason to do this. As
language implementer I have just a different view. I want to know
about such cases long before someone actually has the problem. This
way I can think about an alternate portable way to solve the issue.
Therefore I need to know the details of a certain case. With a
little luck somebody can provide a portable solution before someone
hits the problem.
Maybe not, but also maybe it did.
In general yes, but the assembler is there for the specific cases. I'm a
fulltime Delphi devel, and _all_ of my inline code on the job is SSE2.
Currently your SSE2 code improves performance. In the future it can
happen that equivalent compiled Pascal/Delphi code uses the SSE8
units that provide much better performance. Then your SSE2 inline
code would actually be slower.
SSE is not like normal x86. Vectorization and intrinsics are still no match
for handcoded assembler, although there are a few rare exceptions. Moreover
the corresponding C code (like icc) doesn't look like a naieve
implementation, but is specially crafted.
As far as I know there is no tool that does this automatically based on
naieve code. Not even experimental. So I don't expect this to change in the
My point was: Hand crafted assembler code might be slower than high
level language code compiled with future compilers on future
That's why we also sport an x86_64,ppc,ppc64,arm (several flavours),sparc
and sparc64 assembler. Because the lowlevel parts of the program and RTL
must also be done in assembler for those parts.
So portable programs need to provide code for all this assemblers?
If it is important enough for them to use assembler, and they really want to
support all architectures: yes, why not. Who am I to second guess their
They might even have to add a couple more versions, because ABIs and
alignment rules for x86 vary wildly.
It is really not a good idea when a language encourages writing
unportable programs. Instead of providing backdoors the language
implementers should find out where programmers would consider using
such backdoors and improve this areas.
Encourage and enable are two entirely different things.
Yes, but my view is different.
I want to find out exactly for which problems people consider
backdoors such as inline assembler
Then I want to examine this problems one by one to see if it is possible
to provide a portable way to solve the problem. This way a language and
its library can be improved.
That's a self furfilling prophecy. Because the people see it can't be done
sanely, and have to wait for a solution before actually starting, they
simply go to the next. So you don't get many signals.
We are talking about theoretical cases here. This implies there is
enough time to think for a good and portable solution. Seed7
provides also a solution for the emergency need you are talking
about: It is possible to introduce primitive actions (written in C).
BTW: I see "inline assembler" and sanely as contradiction in terms.
I gave up the idea that I can foresee every potential use and canalize it
every effort exactly how I want years ago. It's a bit a God complex thing,
and it leaves you with a few cheerleaders, but very little general use.
For a long time such things were considered low level and almost
impossible to do in a portable way. Driver librarys available on several
operating systems and language implementations solved the problem but it
is still not trivial: Try to write a portable program with cursor
positioning which works in a windows console and in an linux xterm (when
compiled on this two platforms from the same source code).
Note that aside from this, direct screenwrites were simply absolutely
necessary on a 386.
The Seed7 driver librarys make this possible. Instead of asking the
programmer to use operating system dependend features or external librarys
I decided to provide a solution in the Seed7 runtime library.
FPC does too, but that is because we hope that our implementation covers 90%
of the suitable tasks. For the rest, users can still do it themselves.
In other words, have a standarized interface for it is no reason to disallow
external access. People are fallable, and simply cannot forsee all uses and
Another areas where I tried to avoid unportable programs:
The strings are UTF-32 but when dealing with the operating system
they are automatically converted to the character encoding used
by the system calls (which is UTF-16 on windows and UTF-8 on
And I pity the poor chap that has to regularly stuff a few tens of GBs of
database exports through it. Not even that odd-ball scenario btw.
Are you referring to the CPU time necessary to convert data when it
is read or written? For huge amounts of data coming from a DB or
file the harddisk performance is normally the bottleneck and the CPU
has enough time to do some conversions. At least my hard disk repair
program (see http://seed7.sourceforge.net/scrshots/savehd7.htm) has
no performance problems. There is also a low level byte string, but
until now I did not see any performance requirements which made it
necessary to use it. So I prefer to use the Unicode strings for
all things. If you just want to do something with files: The Seed7
library provides functions to handle files (e.g. copy or move files
or directory trees or do other stuff).
Or do you think that Seed7 just handles UTF-32 files and therefore
expect huge files? This is not the case. Seed7 can handle Byte,
UTF-8, UTF-16(BE & LE) and many more files.
So I am asking:
For which areas programmers consider backdoors and how could
this things be done in a portable way.
For all areas, since the language maker is simply not omnipotent.
Greetings Thomas Mertes
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.