[The context, which the poster below snipped, was questions about
the internal mechanisms of C runtime systems, with particular
respect to function calls.]
In article <11**********************@h48g2000cwc.googlegroups .com>
<ra************@yahoo.co.inwrote:
>learn(and understand) any x86 based assembly lang.
While there is nothing *wrong* with learning any particular assembly
language, it is a huge mistake to learn *only* x86 assembly and
assume that this is the way "everything" works. In particular,
the x86 is largely based on 1970s-era architectures (specifically
the Intel 4004, 8008, and 8080). x86 implementations carry a huge
burden of "backwards compatibility" with a system optimized for
the conditions that held at the time. It is true that, through
great cleverness, modern CPUs that implement the IA32 architecture
squeeze tremendous performance from this klunky instruction set;
but the instruction set itself remains klunky nonetheless.
Compare, for instance, the call sequence:
/* compute three parameters, then: */
push parm3 /* write 3rd parameter to RAM, adjust stack pointer */
push parm2 /* write 2nd parameter to RAM, adjust stack pointer */
push parm1 /* write 1st parameter to RAM, adjust stack pointer */
call func
addl $12,%esp /* remove 12 bytes of parameter from stack */
with:
/* compute three parameters directly into arg registers */
call func
/* no stack adjustment required */
in which we have removed four out of five instructions from the
caller (by using a more-sensible instruction set). Suppose further
that the target function "func" is a "leaf function" -- one that
makes no calls of its own -- so that the x86 version reads, e.g.:
func:
enter /* instruction that builds stack frame; actually faster
to open-code this as several instructions */
... code to work with the three parameters using the frame ptr ...
leave
ret
while the more-modern architecture just does:
func:
... work directly with the parameters in their registers ...
retl /* "return from leaf" */
which eliminates the frame-building (admittedly, a good compiler
can do this on the x86 in some cases, although register pressure
often forces at least some pushes and pops) and 100% of the CPU<->RAM
traffic. The modern architecture's debug system understands that
"leaf functions" do not build stack frames, and use the "return
from leaf" instruction to branch back to the caller (whose return
address is stored in the "caller's return address" register, rather
than RAM, by the "call" instruction).
For a decent smattering of assembly languages, one might learn (at
least the rudiments of) x86, MIPS or SPARC, PowerPC, and ARM.
Investigating the moribund Itanium instruction set, and perhaps
some vector processor instruction sets (Cray or Convex for instance),
might also be worthwhile. Some Data General Nova or Eclipse
experience could also broaden one's concept of "pointers". None
of these are *required* to understand C code, but they will certainly
give you a better idea of the possible ranges for underlying
architectures, and an appreciation for how well (or in some cases
poorly) C maps onto them.
(I might include IBM AS/400 "MIL" above if I had any idea what was
in it. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.