assembly in future C standard

C

CBFalconer

Richard said:
.... snip ...

Note that the term "RDTSC" is meaningless unless you happen to be
using an Intel processor in the x86 family, from the Pentium
onwards, or a clone thereof. Any code you write that relies on an
RDTSC instruction is inherently non-portable.

Which is what Jacob has done in lcc-win32, thus making it unusable
on any 486 system. He obviously has failed to guard its use
against the executing CPU. He can't even find the offensive code,
as of several years ago. This is a good illustration of the
penalties for using non-standardisms cavalierly.
 
R

Richard Heathfield

Keith Thompson said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

If he were capable of giving good advice, he would probably also be capable
of spelling my name correctly.
 
K

Kenny McCormack

Keith Thompson said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

If he were capable of giving good advice, he would probably also be capable
of spelling my name correctly.

Typos hppen.

Don't take it personally. Don't go all girly, girly on us now.
 
F

fermineutron

CBFalconer said:
Which is what Jacob has done in lcc-win32, thus making it unusable
on any 486 system. He obviously has failed to guard its use
against the executing CPU. He can't even find the offensive code,
as of several years ago. This is a good illustration of the
penalties for using non-standardisms cavalierly.

This seems to develop into an optimization problem. That is, compiler
authors have to choose between limiting their code output to
instruction set of older CPUs and perhaps realizing a speed gain from
modern architecture.

For example lets consider realoc function, or more precicely the copy
portion of that function.

The most comforming way would be to move 4 bytes into EAX register from
mem1, then move 4 bytes fom EAX register to mem2, increment mem1 and
mem2 by 4, loop untill all data is copied. Probably moving 1 byte at a
time is even more conforming, since then we do not have to worry wether
the size of the data to be copied is a multiple of 4.

Now a better way for a modern system would be to use the MMX registers,
to copy data in larger chunks.

So the question becomes: should the compiler author implement method 1
or method 2?

Probably 90% of moden CPUs will accept code generated by method 2,
which is allot faster than method 1.

Some compilers will give an option to which set of cpu instruction
limit the compiler output, but not all.

So now, that modern CPUs are quite different from older ones, the C
standard comity is faced with a disision of to what extent, in time,
the C stndard has to be portable. Just like the 32 bit code is not
expected to run on 16 bit machine, why should C code written in
complience with standard XX run on a cpu predated XX. This does not
violate requirement that code written prior to XX standard has to run
on XX standard.

Again ill use an example of RDTSC (ReaD Time Stamp Counter):
A C call to a function tat uses RDTSC is non-portable to older cpus, i
think 586 is the 1st one that recognizes RDTSC. Now, does that mean
that C code which uses RDTSC can not conform to modern day C standard?
I think that when C99 came out RDTSC was already supported by CPUs, so
shouldn't C99 recognize code implementing RDTSC as conforming to C99
standard. If yes then why RDTSC call can not be a part of C99 standard
library.

Naturally mnemonic and opcode for RDTSC cpu instruction will be
different for different processors, but as long as compiler knows what
that opcode for a given cpu is, a compiler can compile code that uses
RDTSC to run on what ever cpu the compiler is intended for.

By the way, returning to the minimal list of cpu instructions, i thing
that thre true bare bone will have 2 instructiions, Move and Add. Move
can be used to read and write, whie add can be used to to addition,
subtraction, multiplication and division. Shift instructions would
speed it up, but are redundant. So if C is to be truly compatible
whith anything and everything, should not it limit the compiler output
to these 2 instructions. Obviously its an overkill, but gets my point
across.
 
F

Flash Gordon

fermineutron wrote:

So now, that modern CPUs are quite different from older ones, the C
standard comity is faced with a disision of to what extent, in time,
the C stndard has to be portable. Just like the 32 bit code is not
expected to run on 16 bit machine,

It is quite possible to write code that will run on 16 bit, 32 bit, 64
bit and any other size machine. You just have to do it correctly,
something that the C99 standard makes a bit easier,
> why should C code written in
complience with standard XX run on a cpu predated XX.

Because a lot of CPUs pre-dating the standard still have code actively
being developed for them.
> This does not
violate requirement that code written prior to XX standard has to run
on XX standard.

Actually, that gets broken to an extent. For example removing implicit
int in C99 means that some valid C89 code is not valid C99 code. Of
course they are selective about such things.
Again ill use an example of RDTSC (ReaD Time Stamp Counter):
A C call to a function tat uses RDTSC is non-portable to older cpus, i
think 586 is the 1st one that recognizes RDTSC. Now, does that mean
that C code which uses RDTSC can not conform to modern day C standard?
I think that when C99 came out RDTSC was already supported by CPUs, so
shouldn't C99 recognize code implementing RDTSC as conforming to C99
standard. If yes then why RDTSC call can not be a part of C99 standard
library.

Naturally mnemonic and opcode for RDTSC cpu instruction will be
different for different processors, but as long as compiler knows what
that opcode for a given cpu is, a compiler can compile code that uses
RDTSC to run on what ever cpu the compiler is intended for.

Now what about the processors that simply don't have anything of the
sort? What about Windows systems which have the problems mentioned here
http://en.wikipedia.org/wiki/RDTSC ? I'm sure the problem is not limited
to Windows.
By the way, returning to the minimal list of cpu instructions, i thing
that thre true bare bone will have 2 instructiions, Move and Add. Move
can be used to read and write, whie add can be used to to addition,
subtraction, multiplication and division. Shift instructions would
speed it up, but are redundant. So if C is to be truly compatible
whith anything and everything, should not it limit the compiler output
to these 2 instructions. Obviously its an overkill, but gets my point
across.

C specifies nothing about what instructions the compiler output uses.
This means that implementers are free to make the best possible use of
the processors instruction set that they can manage.

The C standard attempts to strike a sensible balance between being
possible to implement on a wide range of systems and providing useful
functionality. Since the authors of the standard know rather more about
what systems are out there than you do I'm rather more inclined to trust
their judgement on the matter than yours.
 
J

jacob navia

(e-mail address removed) a écrit :
Seems like you're using an odd definition of "portable" here. On
common platforms assembly is not portable between different
compilers/assemblers on the same OS and architecture, let alone between
OSes. Certainly on a single architecture it's possible to write an
assembler that runs under many OSes, but having just one standard
assembly language even in one OS is _not_ the current state of the
world on everyday architectures--witness the x86 example I gave in the
message you replied to.
Since Mac OS, Windows, Linux and Solaris all run the gcc compiler
and since that compiler has an assembler, using that assembler
makes your code portable to any of those architectures. That is
why lcc-win32 uses ATT syntax and NOT Intel's syntax.
 
R

Richard Heathfield

D

Default User

Keith said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.




Brian
 
E

Eric Sosman

fermineutron said:
Richard Heathfield wrote:

It depends what you need. But the best solution to your immediate problem -
that of performance - lies in choosing better, faster algorithms and
implementing them well. You have a great many gains to realise from doing
this; if you do it well, you may well decide that you have no need for any
assembly language after all. Implementing your current algorithms in some
assembly language or other is unlikely to result in significant performance
improvements.



Well, it seems to me that it is not so much the speed gain as a
functionality gain that can be realized from assembly language. For
example, a while back i wrote a simple C profiler, which parces C file
and inserts RDTSC statements before and after each C statement, hence
determining the number of clock cycles it took to execute that line of
code. [...]

This strategy is almost guaranteed to produce a wrong answer.
Ever done "step to next line" in a debugger after an optimizing
compiler has had a whack at the code? You may have noticed that
the apparent position in the source jumps around a lot: You start
at line L, step once and hit L+1, step again to line L, step again
to line L+3, step again to line L-1, ... Then you look at the
actual instructions, and you see that they're a sort of Cuisinarted
puree of bits and pieces from a whole lot of nearby lines, plus a
few things from lines that are quite a ways off, and maybe even a
few that aren't easily attributed to any particular line at all.

Then again, the presence of all these foreign tidbits may just
tie the optimizer's hands, preventing aggressive reorganizations and
forcing the code generator into a line-at-a-time mode. If so, you've
instrumented something that's quite different from the uninstrumented
programs you'll actually wind up running, and you get a very accurate
measurement of something not very relevant.
 
J

jacob navia

fermineutron a écrit :
Some compilers support __asm{ } statement which allows integration of C
and raw assembly code. A while back I asked a question about such
syntax and was told that __asm is not a part of a C standard. My
question now is:

Is there a chance that such statement will become a part of C standard
in the future? In some cases using asm language is the best way to
acomplish some small task, hence integration of C and asm would greatly
enhence C, or atleast it would in my opinion.

Is there a good reason why __asm is not a part of current C standard?

I have bumped into compilers that support and others that ignore __asm
statement so obviously it is still not a part of C standard.

From the compiler's perspective, the _asm() keyword is quite
difficult...

In lcc-win32 (as in any other compiler by the way) there are some
assumptions about which registers are used/free, which are scratch,
which are saved across function calls and which are not.

If you make some assembly code inline, you better do not
touch those assumptions and follow them 100%. If not, a sure
catastrophe is bound to happen, since the compiler will not
parse asm statements to figure out which registers did you
use.

In general _asm() will interact very badly with the optimizer,
specially the peephole optimizer of lcc-win32. Since
the optimizer is geared to code produced by the compiler, it will
get confused by your asm statements.

To avoid this problems, gcc has developed a language that
has been always a closed book for me, where you describe your
assembly statements to the compiler.

That language is a pure horror, I have never been able to understand
it even after some time spent (wasted?) in it.

Obviously that is a better solution that asm, but it
would be very difficult to standardize.

Because of this problems, asm() usage in lcc-win32 is severely
restricted and fifficult to use. The assembler anyway, is completely
machine oriented, and putting (for instance) an extra blank in
your instruction will produce a crash:
movl -8(%ebp),%eax
is not the same as
movl -8(%ebp),%eax
since in the first line there is a tab (acccepted)
and in the second there are 8 spaces (crash).

Nothing has been done to support asm() really, and with a reason, see
above.

In general is better to put your assembly language functions in
a separate file and use a human oriented assembler, with macros,
and all the things you need to debug your assembly
programs...

jacob
 
K

Keith Thompson

CBFalconer said:
Which is what Jacob has done in lcc-win32, thus making it unusable
on any 486 system. He obviously has failed to guard its use
against the executing CPU. He can't even find the offensive code,
as of several years ago. This is a good illustration of the
penalties for using non-standardisms cavalierly.

I think you're talking about two different things. Richard, I think,
is talking about C code that uses some kind of inline assembly
extension to explicitly specify an RDTSC instruction; obviously such
source code will be portable only to systems that have the RDTSC
instruction (and to compilers that support that particular form of
inline assembly).

lcc-win32, if I understand you correctly, uses the RDTSC instruction
*in the generated code* for C source code that does not expliclitly
refer to it. Translating C source code to machine code is, of course,
what compilers do, and the generated machine code is potentially much
less portable than the C source from which it was generated. If
lcc-win32 generates code that won't work on a 486, that may be
inconvenient for some, but it's not a C language issue.
 
K

Keith Thompson

fermineutron said:
This seems to develop into an optimization problem. That is, compiler
authors have to choose between limiting their code output to
instruction set of older CPUs and perhaps realizing a speed gain from
modern architecture.

For example lets consider realoc function, or more precicely the copy
portion of that function.

The most comforming way would be to move 4 bytes into EAX register from
mem1, then move 4 bytes fom EAX register to mem2, increment mem1 and
mem2 by 4, loop untill all data is copied. Probably moving 1 byte at a
time is even more conforming, since then we do not have to worry wether
the size of the data to be copied is a multiple of 4.

Now a better way for a modern system would be to use the MMX registers,
to copy data in larger chunks.

So the question becomes: should the compiler author implement method 1
or method 2?

Probably 90% of moden CPUs will accept code generated by method 2,
which is allot faster than method 1.

Some compilers will give an option to which set of cpu instruction
limit the compiler output, but not all.

The compiler generates machine code from C source code. How it does
so is not the concern of the C language standard (or of this
newsgroup).
So now, that modern CPUs are quite different from older ones, the C
standard comity is faced with a disision of to what extent, in time,
the C stndard has to be portable. Just like the 32 bit code is not
expected to run on 16 bit machine, why should C code written in
complience with standard XX run on a cpu predated XX. This does not
violate requirement that code written prior to XX standard has to run
on XX standard.

You used realloc() as an example. I can write perfectly portable C
code that uses realloc(); I don't care how the copying is implemented,
as long as it works. Obviously a compiler writer (actually, a runtime
library writer) does care, but that's not a C language issue.
Again ill use an example of RDTSC (ReaD Time Stamp Counter):
A C call to a function tat uses RDTSC is non-portable to older cpus, i
think 586 is the 1st one that recognizes RDTSC. Now, does that mean
that C code which uses RDTSC can not conform to modern day C standard?
I think that when C99 came out RDTSC was already supported by CPUs, so
shouldn't C99 recognize code implementing RDTSC as conforming to C99
standard. If yes then why RDTSC call can not be a part of C99 standard
library.

You want x86 instruction opcodes to be part of the C standard?

No.
Naturally mnemonic and opcode for RDTSC cpu instruction will be
different for different processors, but as long as compiler knows what
that opcode for a given cpu is, a compiler can compile code that uses
RDTSC to run on what ever cpu the compiler is intended for.

There may not be an RDTSC CPU instruction. There may be something
similar to it that behaves differently in some critical way.

If you want to write C, write C. If you want to specify individual
instructions write assembly language (possibly via some *non-standard*
compiler extension).
By the way, returning to the minimal list of cpu instructions, i thing
that thre true bare bone will have 2 instructiions, Move and Add. Move
can be used to read and write, whie add can be used to to addition,
subtraction, multiplication and division. Shift instructions would
speed it up, but are redundant. So if C is to be truly compatible
whith anything and everything, should not it limit the compiler output
to these 2 instructions. Obviously its an overkill, but gets my point
across.

Not really. Generated code is not portable. And, of course, move and
add are not nearly sufficient for general programming.

C source code specifies the behavior of the compiled program, in
accordance with the standard. It says nothing about the CPU
instructions used to implement that behavior.
 
I

Ian Collins

fermineutron said:
Richard Heathfield wrote:





Well, it seems to me that it is not so much the speed gain as a
functionality gain that can be realized from assembly language. For
example, a while back i wrote a simple C profiler, which parces C file
and inserts RDTSC statements before and after each C statement, hence
determining the number of clock cycles it took to execute that line of
code. Now the only compiler that my profiler will work with is lcc
because the RDTSC is a part of intrinsics library of LCC, but it is not
a part of BC++ 5.02 for example. Had there been a full support for
assembly code within C I could have used inline assembly to do this and
not rely on intrinsics library of LCC.
I'd suggest you look for a tool chain that gives you this functionality
so you don't have to mess with the code. As Eric pointed out, you
probably are profiling something completely different form what you
would have without the intrusive test code.
 
R

Rod Pemberton

Default User said:
Keith said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

Pemberton is a troll.

Brian

My post was an accurate and informative response to the OP's question, with
covered both the issue of C and other languages which applied.

No. You're a troll and a coward. Be brave: use your last name (Rodenborn)
..


Rod Pemberton
 
R

Rod Pemberton

Keith Thompson said:
Rod Pemberton said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

How so? It appears that your response is incorrectly biased...

Heathfield's response was totally incorrect and borders upon incompetence.
My response was the best introduction to the minimal necessary interface to
C and various C libraries and other languages that he'll ever get. He won't
find anything even remotely close in hundreds, if not thousands, of
programming books.


Rod Pemberton
 
R

Rod Pemberton

Richard Heathfield said:
Keith Thompson said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

If he were capable of giving good advice, he would probably also be capable
of spelling my name correctly.

I'm sorry that I unintentionally mispelled of your name out of a thousand or
so. You know that I haven't mispelled it elsewhere. I guess it was a
convenient excuse for you to ignore the fact that your response was totally
incorrect and borders upon incompetence.

I'll reiterate:
My response was the best introduction to the minimal necessary interface to
C and various C libraries and other languages that he'll ever get. He won't
find anything even remotely close in hundreds, if not thousands, of
programming books.


Rod Pemberton
 
B

Bill Reid

Default User said:
Keith said:
You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.
Pemberton is a troll.
Yeah, but closer to being on-topic, albeit no less wacky than
on any other topic...

....and isn't "Rod Pemberton" actually a porn name?
 
K

Kenny McCormack

Keith Thompson said:
Rod Pemberton said:
Theoretically it seems possible to develop a subset of assembly
languages which are used by motern CPUs and include in a C standard a C
library which would allow user to use the assembly subset. Since it is
a limited subset and its sintax is goverened by C it should not present
portability challenges with possible exception of older systems. any
thoughts about this?

You should ignore any response Healthfield gives to your question.
[snip]

That's really bad advice.

How so? It appears that your response is incorrectly biased...

Heathfield's response was totally incorrect and borders upon incompetence.
My response was the best introduction to the minimal necessary interface to
C and various C libraries and other languages that he'll ever get. He won't
find anything even remotely close in hundreds, if not thousands, of
programming books.

Don't feed the netcop.

Also, bear in mind: Don't wrestle with a pig (and you know the rest).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top