Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Disadvantages of Assembly?

21 views
Skip to first unread message

Randall Hyde

unread,
Oct 16, 2001, 10:02:42 AM10/16/01
to

<ccr...@crayne.org> wrote in message news:9qgasu$7h1$1...@odin.asgard...
> In <IKMy7.6317$ks.12...@news2-win.server.ntlworld.com>, on 10/16/01
> at 02:55 AM, "Beth" <BethS...@hotmail.NOSPICEDHAM.com> said:
>
>:For instance, one ASM instruction is "mov eax, ebx", which means to move
>:a 32-bit value from one processor storage area to another and that's
>:it...
>
>:Whereas, one C statement is "printf", which uses the C calling convention
>
> Beth, I agree with the overall tone of your answer, but I don't think that
> you are making the case strongly enough. To begin with, it would be more
> to the point to say:
>
> 'For instance, one ASM instruction is "inc myvariable" whereas, the
> corresponding C statement is "myvariable++"'.
>
> Sure enough, the C statement is slightly shorter, but not enough so as to
> significantly affect productivity. As to readability, both are clear
> enough to one who has had some exposure to them, and both are equally
> cryptic to those who have not seen either form before.

Of course, when one considers a statement like:

x = (y+2)*(z-a+b)/( (int) (c / 2.0) -1)

and the corresponding assembly code, one could easily argue that
the C is *is* easier to understand (not that the code above is
crystal clear, but...)

>
> In addition, if one takes the word "statement" in terms of the formal
> description of the C language, your comment that 'one C statement is
> "printf"' is incorrect. There is no "printf" statement in C. Instead, the
> C syntax is that "printf(. . .)" is a call to a subroutine named "printf".
> The corresponding ASM syntax is "call printf".

Plus passing all the parameters, of course.

>
> To generalize, although it is true that to write ASM code one must have a
> knowledge of the target computer's architecture, the real strength of C is
> not the language itself, but the existance of a robust standard subroutine
> library which can be assumed to exist on every target architecture.
>
> This has never happened in ASM, because ASM programmers are too
> individualistic to have ever agreed on a standard subroutine library for
> even one computer architecture, let alone multiple platforms.

Generally, though, standard libraries don't come into existence because
a much of programmers agreed on the set of routines. Instead, one
individual, or a small team, creates the library and it gets adopted by
others. Ultimately, some organization may put their "seal of approval"
on the library, but they almost always start out as the work of an
individual or a small team.

There are, btw, thousands of people out there using the "UCR
Standard Library for 80x86 Assembly Programmers." Hardly
multiplatform (really exists only for DOS), and nowhere near
as ubiquitous as the C Standard Library, but it has done
surprisingly well for itself.
Randy Hyde


Randall Hyde

unread,
Oct 16, 2001, 10:02:43 AM10/16/01
to

<ber...@ami.com.au> wrote in message
news:3bcb76fa...@news.ami.com.au...
> The problem with HLLs is that there is no way of knowing how the
> library routine work. You simply have to take it on trust. If you scan
> through them with a debugging package such as Codeview they seem to
> take an age to do somthing which you could write in assembly in a few
> lines.

Well, most libraries these days are available in source form.
As to the excess code you allude to, this situation usually exists because
the library routines are general and handle lots of special cases; it's not
surprising to find that you can produce shorter code for the particular
special case you need to address. This is the disadvantage of use
a (well-designed and well-written) library routine. This problem is
independent of language; it exists for library routines written in assembly
language, as well.

Randy Hyde


ccr...@crayne.org

unread,
Oct 16, 2001, 5:03:02 PM10/16/01
to
In <umWy7.1121$z_5.38...@newssvr21.news.prodigy.com>, on 10/16/01
at 02:02 PM, "Randall Hyde" <rh...@transdimension.com> said:

:Of course, when one considers a statement like:

: x = (y+2)*(z-a+b)/( (int) (c / 2.0) -1)

:and the corresponding assembly code, one could easily argue that the C is
:*is* easier to understand (not that the code above is crystal clear,
:but...)

I am glad that you picked this example, because it demonstrates one of the
weakest points of HLLs in general, and of C in particular -- that for
certain input values, an innocent looking arithmetical expression may
generate incorrect results.

In mathematics, the expression a/2 + b/2 produces the same result as
(a+b)/2 for all values of a and b, but this is not true in C. For example,
let a and b be odd positive values of type int. In all such cases, the
first form yields an incorrect answer which is one lower that the correct
answer yielded by the second form.

If you think that this example is too obvious, consider the cast to
integer in your example. Without looking it up, do you know what the
result of that cast will be if c is a negative number of type float? Now
that you have looked it up, how many C programmers do you think would
remember that consideration when coding such an expression?

Of course, when one codes an integer division in assembly code, the same
truncation issue arises. However, since an assembly language programmer
knows that the remainder is returned in a different register than the
quotient, one is far more likely to consider the need for dealing with
that remainder.

So, although your example may appear to be easier to understand, it is, in
fact, a snare for the unwary.

-- Chuck Crayne
-----------------------------------------------------------
ccr...@crayne.org
-----------------------------------------------------------

Terje Mathisen

unread,
Oct 17, 2001, 1:56:02 AM10/17/01
to
ccr...@crayne.org wrote:
> In mathematics, the expression a/2 + b/2 produces the same result as
> (a+b)/2 for all values of a and b, but this is not true in C. For example,
> let a and b be odd positive values of type int. In all such cases, the
> first form yields an incorrect answer which is one lower that the correct
> answer yielded by the second form.

Except for one _extremely_ common example: When the addition can
overflow!

This happens when decoding MPEG images, using motion compensation to
increase compression:

This code needs to take the average of 8-bit pixels, which means that if
you first add them together, and then divide by two, you've pushed any
carrries from the first byte into the next pixel(s).

OTOH, shifting each part down first, does give useful (but not correct!)
results. (The correct result is what you get from effectively doing

(a+b+1) >> 1;

This can be rewritten as

(a >> 1) + (b >> 1) + ((a | b) & 1);

which works without ever needing more than 8 significant bits, and which
can be used by MMX/SSE asm code.

> So, although your example may appear to be easier to understand, it is, in
> fact, a snare for the unwary.

This is something I agree with. :-)

Terje
--
- <Terje.M...@hda.hydro.com>
Using self-discipline, see http://www.eiffel.com/discipline
"almost all programming can be viewed as an exercise in caching"

Randall Hyde

unread,
Oct 19, 2001, 8:56:00 AM10/19/01
to

"Tim Robinson" <timothy.robi...@ic.ac.uk> wrote in message
news:9qno2d$pc6fg$1...@ID-103400.news.dfncis.de...

> Calling a virtual member function of an object, in assembler:
>
> push param3
> push param2
> push param1
> mov ecx, object
> mov eax, [object]
> mov eax, [eax+14h]
> call eax
> add esp, 12
>
> In C++:
>
> object->member(param1, param2, param3);
>
> Clearly, in the case of assembler vs. C or C++, each language has its
merits
> when it comes to low-level system programming. In the case of writing a
> high-level app, IMO C++ is best simply because it does the things you need
it
> to best.
>

How about in HLA (which I claim is still assembly language)?

If "object" is a static variable:

object.member( param1, param2, param3);

If "object" is a pointer variable:

object.member( param1, param2, param3);

Of course, there are limitations on the format the parameters can
take (e.g., no arithmetic expressions), but most of the time
you're passing constants, registers, or simple variables so HLA's
syntax remains quite similar to a HLL.

Note, btw, that if you truly prefer the "pure" assembly syntax,
HLA allows that, as well.
Randy Hyde

0 new messages