Re: Question about jumps




Frank Kotler wrote:

Erm...

You can do this in Scheme, C, Lisp, Python, Perl, Haskell, and
Brain***
even.

Sure. And if he wanted to do that, he should get the hell out of here
and take it to alt.lang.brain***!

Except you've missed the point that writing numeric I/O routines isn't
what he's really trying to do. What he's trying to do is verify that a
shift left operation multiplies the operand by two. That should be a
*big* clue to the level of "assembly language maturity" Markus has
achieved at this point. If he's just learning that a shift left
operation multiplies its operand by two, do you *really* think he's
ready to write his own numeric I/O routines?



The fact of the matter is that the most common "assembly language" way
is to link up with the C library and then use atoi or whatever.

"Common" in what circles?

Probably Win32/MASM32 circles.
It certainly isn't the common way in HLA circles, as HLA already has
conversion routines for this purpose. And they're written in assembly
language :-)


But yeah; you can do this in C. In fact; there is an example
in the book "The C programming language" where they solve
this problem.

This has _nothing_ to do with assembly language.

If you do it in Brain*** it doesn't have anything to do with assembly
language, either. No ***.

I think the point being made is that the algorithms one uses to do
numeric conversion are independent of the language. "Understanding
what's under the hood" (which is Markus' claim) with respect to numeric
I/O doesn't require learning assembly language. Nor does learning
assembly language explain what's happening "under the hood" because the
vast majority of numeric I/O conversion routines are written in some
HLL. The point being: the algorithms associated with numeric I/O
conversion are independent of the implementation language
(specifically, assembly language in this case).



stdout.put( "Enter an integer:" );
stdin.geti32(); // Read integer from stdin into EAX.
shl( 1, eax ); // Multiply EAX by two
stdout.put( "eax = " );
stdout.puti32( eax );

So why should I deal with assembler, when I could solve it with C-like
methods? That's not what I want to learn.

You can't touch eax in C.

return (42);

Uh, no part of the definition of the C programming language, even as
implemented on the x86, requires function results to be returned in
EAX. So this rebuttal is *very* implementation dependent. You could
just as well claim that a statement like "unsignedVar = uns2 * uns3;"
touches EAX (and EDX, for that matter). The point being made, of
course, is that you don't have control over the machine resources with
using a HLL like C.


Are you listening? "That's not what I want to learn." Do we have to wrap
it in an "if" and "stdout.put" before you guys can comprehend that?

Markus doesn't know *what* he wants to learn. He certainly doesn't know
the best way to go about learning this stuff (and that's no specific
criticism of Markus, *few* students, especially self-taught ones, know
the best way to learn a subject because they don't know what's
important and what's not important when studying the material). Markus
is clearly suffering from an "elitist" attitude of "if I know assembly
language I will be totally cool because I'll know how things work in
ways that HLL programmers will never know." Unfortunately, Markus seems
to be interested in immediate gratification with respect to this
knowledge, wanting to see amazing results and understand everything all
at once. It just doesn't happen that way. You either put in a concerted
effort and learn the material (in a reasonable order and fashion)
quickly, or you spend years slowly absorbing it by experience. Markus
seems to be headed down the second path. That's fine; if he's more
comfortable with that approach then more power to him. But the bottom
line is that he'd learn the stuff a little be faster if a few "if" and
"stdout.put" statements *were* thrown in.


Now you get to see the effect of the shl instruction without having to
learn all the stuff needed to write your own integer input and output
routines. Sure, at some point you ought to be able to write your own
input and output routines, but for right now the integer I/O routines
in the HLA stdlib are *perfect* for the job.

(don't dislocate your shoulder there, Randy! :)

Hey, it sure beats the pants off calling int 0x80 and then claiming shl
doesn't really multiply the result by two.



It's not my target to see what's happened when I type in a number and see
the result on stdout. That's what computer newbies are probably interested
in but I want to understand what the little gremlins in the background are
doing while this happens.


I just fail to see what HLA does that prevents this.

True. (once you've got the file open :) So why don't the HLA fans
provide an example that *shows* how the little gremlins work, instead of
telling him "just call stdout.put"?

Uh, download the stdlib source code if you want to see the numeric
conversion. Then, of course (as long as you've brought up file I/O),
there is the little issue of we're still *far* away from how it really
works. Do you realize how much work the OS is doing for you? Let's take
a single character output from the numeric output conversion routine.
The OS has to render it using the system font (a heck of a lot of
work), it has to draw the rendered image on the screen (and given the
number of different video cards out there today, that's a *heck* of a
lot of work). Then there's the matter of switching between user and
kernel space and passing information between the two. Where do you
draw the line? What's so special about the numeric conversion routine
that doesn't apply likewise to the rest of the output chain?

I'll tell you where it stops -- it stops with the subject being
studied. As learning about SHL's properties with respect to binary
numbers has *little* to do with numeric conversion algorithms, there is
no need to drop down to that level of abstraction when studying SHL.
It's just a distraction that prevents someone from fully learning what
they really set out to learn -- that SHL multiplies its operand by two.
A good educational environment avoids such distractions.




If you want to write your own itoa or atoi routine... assembly
is not the language to do that.

Right. High level languages have some special magic that allows 'em to
do it. Are you *listening* to yourself?

Actually, the language choice is irrelevant. What's important is the
algorithm. And again, that algorithm has nothing to do with the subject
at hand, which is learning how the SHL instruction operates.



Well; you _can_ of course;
just... atoi isn't a "little gremlin" at all.

No, it's a sequence of machine instructions. Markus has made it fairly
plain, I thought, that he wants to know what that sequence of
instructions *is*.

But Markus is not in the best position to know *when* it's appropriate
to learn such things, now, is he? Markus is the *perfect*
counter-argument against Herbert's claims that a beginner can figure
this stuff out on their own and that there is no need to provide
library routines to do things like numeric conversion.


For that matter; where do the "little gremlins" stop? I mean; all
you're
doing right now is calling the linux kernel. Aka: using the linux
kernel as a library. Where does "read" and "write" come from?

A very good point.

How far will you go before you're satisfied?

*That's* the question! If we start seeing bootsector questions from
Markus, we'll know he *wasn't* satisfied with "read" and "write". We
already know he's not satisfied with "just call printf".

You seem to assume that everyone is saying "printf will work for you
forever, you don't need to understand how it works." Whether this is
true is irrelevant. The bottom line is that Markus' assembly language
knowledge hasn't reach the level where he *can* understand how "printf"
works. So best to use "printf" now and continue learning assembly
language until his level of expertise rises to the point he *can*
understand how
"printf" works.



Most ironically of all is probably the fact that none of your assembly
code would work without the C code that built the Linux kernel.

Another good point. Since "printf" is (highly probably) already in
memory, why clutter up memory with a HLA routine that duplicates it?

Very simple: have you tried *calling* printf from assembly language? Is
this something you want to wish onto someone who is trying to figure
out how SHL works (have you forgotten his earlier question asking how
in the world the printf-based code he was getting from Carter's book
was working?). Then, of course, there's the issue that many people
don't know how printf's format strings work (though I would assume this
does not apply to Markus who professes a knowledge of C). HLA's output
routines are a bit simpler to understand for those who've not grown up
with C.

As for "Cluttering up memory", HLA's routines are quite a bit smaller
than printf (which has to drag a huge interpreter around with it, in
addition to the individual numeric I/O routines). HLA's code is *much*
smaller.



(unless you prefer a routine written in assembly language...)

The *simple* way to do this:

global _start
_start:
mov ebx, 21
shl ebx, 1
mov eax, 1 ; __NR_exit
int 80h

or just load it into gdb. The problem with this approach is that you
don't get any control over the output format (e.g., radix). Granted,
this doesn't matter for testing SHL, but one step up in complexity and
now it no longer works.


You've gotta type "echo $?" to see the result, and it'll only display
the low byte. If that's not acceptable, "printf" is sitting in memory,
Not difficult to call it...

But it's not difficult to call HLA's stdout.put macro, either. What's
the difference? Indeed, as I recall Markus' earlier question involved a
call to printf (and why ENTER was being used). This is one point I just
don't see -- why is it important to see under the covers with respect
to HLA's stdout.put macro and it's not as important when calling printf
in the C stdlib?



; and print the result - C likes
; its parameters on the stack,
; leftmost one last.

And this is exactly the problem. Someone who's just learning about SHL
probably doesn't know about calling conventions or even what a stack is
and what push does.

push eax
push fmt_int
call printf

etc.

;-------------------

From there, it's an easy step to display the number on the top of the
FPU stack. If Markus wants to know how *that* little gremlin works...
well... have to find that link to Ray Filiatreault's site... but that,
too, is a sequence of machine instructions that can happily be
represented in assembly language... (a *lot* more assembly language than
displaying an integer!)

If Markus really wants to see how stdout.put works, the full source
code to the HLA standard library is there. You don't have to read some
web site that explains how someone else's printf works (versus the one
you're actually calling).
Cheers,
Randy Hyde

.


Loading