• Advertisement
Sign in to follow this  

Thoughts on Nasm, etc..

This topic is 1767 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey GDers,  I was studying some Nasm today and had something of an epiphany.  It might be odd, but I realized something about assembly programming that may or may not have dawned on others before me.  In order to avoid ranting I have noted several specific things based on Netwide Assembler that I beleive makes writing code in assembly  - and call me crazy - easier (for better or worse) than writing in some high-level languages:

 

IMO

 

Nasm makes the math easier

 

- I so very hated math in highschool because like a lot of people it just wouldn't stick.  Folks have been back and forth about whether or not this plays any significant role in a programmers ability.  From my perspective, no it doesn't really matter so long as you do recognize a lot of the mathematical formulas as they were taught from the get-go.  Chances are you'll have to morph the way you think for the language itself anyway(cough cough X,Y coordinates).  In turn,  Assembly, being so damn manual, can turn a complicated string into something much more systematic and therefore making it so that you're under the hood using ADD and SUB (INC, DEC etc) instead of "If" statements laced with multiplication and division.  Given,  that's a double edged sword isn't it? Which brings me to my next point.

 

It's like, the computer is the tree..and I'm the hugger.  And then you have these chainsaws..

 

- You can jerry-rig whatever the hell you need to with some well written assembly.  The way I see it is, there's an apple in the tree(a computer problem),  you can either (solve the problem by..) start building a fine staircase with assembly,  straight up climb the tree yourself with C or chop the tree down with say..Perl and walk off with all the fruit with a bag made of leaves, screw what the tree looks like now, right?  I like being close to the hardware but that's not the point.  In fact I've always just wanted to use that analogy so don't mind me.  I'll just move on and say..

 

The syntax doesn't bother me

 

 - you will run the other way when you see perfectly good grammar being slaughtered (in a good way) for the sake of making syntax "easier".  If you're anything like me you will see the "elsif" (I love perl) statement and go 0_o ugh.  I'm not even going to bring up graphics libraries, those mouths are just filthy.  Mov, dd, db and even EAX makes more sense to me because it looks like it's supposed to be abbreviated.  But I love high-level langauges nonetheless.  It's like pseudo-code on top of code on top of comments.

 

Assembly literally makes you feel the structure

 

- Which is what I think the real allure is.  It's the fact that you can reallly get into the nooks and get stuff done.  Also, I want a share a little tip to folks learning x86 assembly because it helped me out, if any pros out there want to share/correct anything in turn that's be badass but here I go.

 

operation    destination    source

 

is some common format seen in the assembler.  The best way I memorize and apply this is by thinking:

 

The mission the target and rendevous (except you rendevous before taking out the target, hitmen can be team players too.)

 

or if you're not weird just zone in on the destination being the middle most accessible part of a road of some sort and by adding labels and directives etc etc you're adding lanes to it. But have these lanes be specific similar to how there are bike lanes and HOV lanes and hell, trolley car lanes in real life.  Just my two cents.  What are your thoughts on assembly in 2013?

Edited by iGoogleThis

Share this post


Link to post
Share on other sites
Advertisement

Assembly is a thing of the past, it *can* be usefull to write a couples of inline assembly code for beginers, like me once, who didn't know how to make some simple operations in c++ code, like playing with bitfield, simple stuff like that, however i doubt you'll get very far nowaday writing only in assembly. Try making a 10000 lines of code project in asm and tell me how it goes tongue.png . One of the only thing i could think of using it for is for bit rolling (ror, rol), emulators, or to make floppy boot disk, which are almost non-existant in 2013. If you want to decrease your productivity by 10x (compare to c++) or 100x (compare to c# and delphi), then go for it... And i don't see how it make the math easier either... Have you tried multiplication, division, signed integer, floating point??? Probably not...

Edited by jbadams
Restored post contents from history.

Share this post


Link to post
Share on other sites

I think assembly / a compilers class / an OS class are all majorly useful to understand.

 

Knowing what a compiler or OS is doing takes a lot of the mystery out of what the computer is doing.  When you realize that while/for can be written with if/goto and functions are just gotos that clean up code, you'll realize the answers to a lot of beginner questions like "when do i use while(){} vs do{}while vs for?".

 

Also compilers optimize. I've been in a lot of situations where writing assembly isn't important but reading it is. And understanding what the compiler probably did is equally important. The "release" build of most code looks nothing like the output of a debug build. When you get a crash, chances are it doesn't line up well with the code the debugger claims crashed. Even when it does line up, logic and values are still often folded out by the compiler. Being able to understand the assembly to what the code is actually doing is the only way to discover some types of bugs efficiently.

Share this post


Link to post
Share on other sites

Have you tried multiplication, division, signed integer, floating point??? Probably not...

 

Of course I have, that's the law of the land. 

 

I want to note, assembly is not my primary language but I am learning it because I write code in C primarily.  As KulSeran said:

 

Being able to understand the assembly to what the code is actually doing is the only way to discover some types of bugs efficiently.

Share this post


Link to post
Share on other sites
I spent many years hand-tuning assembly for EGA, CGA and later VGA/ModeX. Back then, bare-metal programming was not only "all the rage" it was necessary if you wanted to achieve acceptable levels of performance. You had to know your assembly. Now, though... while I won't argue that knowing things on the assembly level isn't useful (all knowledge is useful, in one way or another)and fun, it is inarguably far less vital. It is possible to become a very competent developer without ever touching it. In fact, I'd even go so far as to say that for developers up to a certain (undefined) level of expertise, it might be dangerous to dabble too deeply into assembly. Writing assembly now is pretty far removed from what it once was. Optimization is just so different from what it used to be, that you are almost always better off letting the compiler do it rather than trying to do it yourself. And I'm not convinced that it really can help you to become a better programmer anymore, unless you're a kernel or driver hacker. Modern programming takes place on top of so many layers of abstraction, that the actual details of the underlying hardware are almost irrelevant. And you certainly won't find very many job listings that list it as a requirement. It arguably might make you marginally better at debugging, but if you are planning your education arc around something that will only come in handy in a small number of cases, I worry you might be wasting your time.

Now, if you're doing it for the joy/learning/bragging rights, or you want to be a kernel developer, a driver developer, or a compiler developer, then knock yourself out. But beyond a small handful of niche specialties, it's just not all that useful anymore. Edited by JTippetts

Share this post


Link to post
Share on other sites

JTippets,  I didn't want to beleive it!  But coming from someone who's been there I can definitely see what you're saying.  Still though for the sake of grunt development (kernel, drivers etc) what's the best way to really go about applying it?  I find that the documentation is alright but the application is verry limited.  I suppose this goes back to what you said about it just not really having a place anymore.

Share this post


Link to post
Share on other sites

Assembly, being so damn manual, can turn a complicated string into something much more systematic and therefore making it so that you're under the hood using ADD and SUB (INC, DEC etc) instead of "If" statements laced with multiplication and division.

You can write in that style in a higher level language if you like:
void SUB( int& a, int b, int c ) { a = b - c; }
void ADD( int& a, int b, int c ) { a = b + c; }
void SET( int& a, int b )        { a = b; }
void PRINT( int a )              { printf("%d\n", a ); }

int main()
{
  int foo, bar, baz;
  SET( foo, 1 );
  SET( bar, 2 );
  ADD( baz, foo, bar );
  SUB( foo, baz, foo );
  PRINT( foo );
}
In high school, we had a class where we learnt to use a "CPU simulator", which was a PC program simulating a simple RISC CPU with a simple assembly language, and a small array of bytes of RAM to operate on.
I still remember being absolutely stumped when being asked to write a routine on this "CPU" to calculate the square root of a user-inputted value, and then being ridiculously excited once I started putting together the ASM building blocks to a solution (and then competing with the other kids to shave instructions off our solutions to get the most compact one)!

It is a great learning exercise, but it's very rare to actually need to use assembly in day to day programming tasks.

Share this post


Link to post
Share on other sites

Assembly is a thing of the past

Not if you've spent any time doing some serious debugging (especially on the PS3).

 

Inline assembly maybe, but if you're trying to track down a bug that only occurs in your retail/release build it's pretty much essential. 

Edited by Orangeatang

Share this post


Link to post
Share on other sites

I can definitely understand your enamourment with assembly language smile.png

 

I cut my teeth as a budding software developer on 68k and z80 assembler for my calculator.

Almost no OS in the way, and full control. C compilers felt ridiculously bloated. 

 

Professionally though, over the last 10 years, I've produced a single line of assembly that was included in production code. (that single line of asm was in 200+ million phones worldwide though, so not bad smile.png )

 

As everyone else says, with compilers getting better, and hardware more complex, hand assembler optimization is getting less and less important.

 

And knowledge is never a bad thing!

For anyone who wants to write performance critical code, its very useful to know your asm enough to at least inspect your compilers effort.

 

I'd never want to be without my OOP when the problems get a bit more complex...

Edited by Olof Hedman

Share this post


Link to post
Share on other sites

Im not saying that it's dead, in fact i know a good deal of assembly language, but i wouldn't say it's better than higher level language. Still, it's fun to play with and you can learn a great deal of how the processor really work.

Edited by jbadams
Restored post contents from history.

Share this post


Link to post
Share on other sites

When I was a kid, the progression to learning programming was BASIC first, then assembly. You couldn't get a C compiler for free back then, and DOS came with 'debug' letting you write little assembly programs.  Later I moved onto C(++), Java, etc, and never went back to it.  But I do understand your fascination with it, and at times, something I think about getting in to x64 assembly programming.  Maybe later.

 

Don't let others give you grief about it though.  I'm a hardcore C programmer, and even program C in an OO style (function pointers in structs for polymorphism, etc), and some people give me trouble for it.  I understand C++ is there, but for my own personal projects (not at work: at work I use whatever the rest of the team is using because its not my project) I choose C.

 

Keep doing what you're doing.  We need more assembly programmers, because somebody needs to fix the compiler when it spits out broken code, or write those high performance hardware drivers!  

Share this post


Link to post
Share on other sites

You can write in that style in a higher level language if you like:

 

Are those prototypes up there above the main function or just globals?  Either way I can't wait to get good enough at it to throw a few for-fun versions of that down from off the top!

 

  1. Write first for correctness, properly weighing performance against maintainability, and choosing good algorithms.

 

Ravyne your entire post was super insightful!  That number 1 is definitely the key, figure if you can do that part right then optimazation should become less and less of an issue.  For me I'd rehash the thing till it's blazing fast and after awhile I suppose if you're good enough at that you can almost fit all of those steps into just number one there from the start.  My C code can be unruly at times because I like to avoid using too many pointers but that's a whole different topic.  Suppose to goes back to the performance thing being essential.

 

I'm a hardcore C programmer, and even program C in an OO style (function pointers in structs for polymorphism, etc), and some people give me trouble for it.  I understand C++ is there, but for my own personal projects (not at work: at work I use whatever the rest of the team is using because its not my project) I choose C.

 

 

DracoLacorente, Was that style something you eased into on your own?  I'm self-taught so it's a lot of give and take when it comes to style.  I actually started off learning Python somewhat formally but it was so whitespace-unfriendly.  The freedoms C gives you while staying kind of centered is why I like it.  That and of course the inline assembly capability that people frown upon.  I don't want to be that guy but it honestly just rings my bells.

 

I've seen it answered a few times but how does inline assembly fare as far as portabliity goes?  I don't do it at all yet but would that make it slightly more portable or the opposite? 

Edited by iGoogleThis

Share this post


Link to post
Share on other sites

Ravyne your entire post was super insightful! That number 1 is definitely the key, figure if you can do that part right then optimazation should become less and less of an issue. For me I'd rehash the thing till it's blazing fast and after awhile I suppose if you're good enough at that you can almost fit all of those steps into just number one there from the start. My C code can be unruly at times because I like to avoid using too many pointers but that's a whole different topic. Suppose to goes back to the performance thing being essential.

 

I'm glad you found it useful, but I'm worried you misinterpret it a bit -- I want to drive home the point that is in no way meant to be viewed as something you can compress into a single step, nor should you want to. It's a process that aims to put your efforts squarely where they belong, while leaving code at the most abstracted level that it can meet performance requirements in. Trying to compress it all into one step is impossible without making dangerous assumptions that will end up costing you time, maintainability, and performance. An expert might skip steps 6 and 7 if, and only if, they are certain through wisdom and experience that the compiler cannot or will not generate the best code -- but they will never simply assume that to be the case, nor would they skip the earlier steps without first having hard data to prove that it falls into a performance hot-spot.

 

I'll share something I learned just yesterday which is tangential but illustrative of why the thing you think will work best, often doesn't.

 

I attended a meeting of the Northwest C++ Users Group last night. The topic was Visual Studio's Profile-Guided Optimization (PoGO, for short) feature and how it works. In brief, PoGO works by instrumenting a build of your application which you then run through various performance-sensitive scenarios in order to train it with real data. Then, you do the real (release) build in a way that incorporates that training to help inform the compiler how to generate the best code for real use-cases. For example, based on whether the conditional is likely to be true or false, it might swap the order of conditional branches in an 'if' statement so that the processor speculatively executes the correct branch in the majority of cases. If it does so, the CPU stalls less, and performance is increased. It also applies what it's learned about how-often, and from where every function call is made (this infuences whether the function should be inlined or not). It's all very complex, and I'm simplifying it here, but that's what it does in a nutshell.

 

When we got to the end of the presentation and the speaker was comparing results of PoGO-compiled code vs code compiled with -O2 (the highest level of non-PoGO optimization Visual Studio's compiler supports) there were some really interesting results. Not only was the PoGO-compiled code faster, it was also smaller, and it also only inlined about 5% of the overall call sites, vs around 20% or higher that were inlined by the -O2-compiled code. Now, it performs a number of other optimizations to achieve that, but think about those stats on their own -- The PoGO code used far less inlining than the -O2 code, and was faster and was smaller, all at the same time. Best performance is not achieved by being most-agressive with potential optimizations, its achieved by being really smart about where optimizations are applied, and by applying them in the context of real data about real scenarios.

 

Lets think about that another way: For all of the thousands of PhD-hours and hundreds of millions of dollars thrown into compiler research over decades, not even the compiler (and one of the best in the world, at that) can generate its best code without first profiling it!

Edited by Ravyne

Share this post


Link to post
Share on other sites

  •  
Quote

I'm a hardcore C programmer, and even program C in an OO style (function pointers in structs for polymorphism, etc), and some people give me trouble for it. I understand C++ is there, but for my own personal projects (not at work: at work I use whatever the rest of the team is using because its not my project) I choose C.




DracoLacorente, Was that style something you eased into on your own? I'm self-taught so it's a lot of give and take when it comes to style. I actually started off learning Python somewhat formally but it was so whitespace-unfriendly. The freedoms C gives you while staying kind of centered is why I like it. That and of course the inline assembly capability that people frown upon. I don't want to be that guy but it honestly just rings my bells.

 

 

I had zero style throughout high school and most of college.  Even after college my style was somewhat poor.  It was after working at my current company for about a year or so that some of the style and design of the code at work began to rub off on me an influence my code at home.  There's a few key experiences that have shook my style quite dramatically:

 

 

  • I took a Java class at school.  The ideas of objects and polymorphism were cool, but I saw a lot of stuff that seemed over-OO-ified.  (the Integer class, for example).  But the idea of interfaces and abstraction really influenced my style.

 

 

  • At work, one of the projects I help maintain is a large C codebase.  It has full manual memory management.  It sucks.  There is one part of that code base (a data tree structure) that uses reference counting.  I've adopted reference counting in my home-coded C projects.
  •  

This is typical of my style at home:

 

typedef struct inner_s {
   char* str;
   void (*do_something)(struct inner_s* inner);
} inner_t;

typedef struct {
   inner_t* i1;
   inner_t* i2;
} outer_t;

void free_outer(outer_t* x)
{
   z_free(x->i1);
   z_free(x->i2);
}

void foo(outer_t* x)
{
	x->i1->do_something(x->i1);
	x->i2->do_something(x->i2);  
}


void free_inner(inner_t* x)
{
  z_free(x->str);
}



void inner_do_something_interesting(inner_t* in)
{
  printf(" oh my god %s!\n", in->str); 
}

void inner_do_something_boring(inner_t* in)
{
  printf("I'm bored\n");
}

inner_t* inner_mk(char* string)
{
   inner_t* inner = z_alloc(sizeof(*inner), free_inner);
   inner->str = z_addref(string);
   inner->do_something = inner_do_something_interesting;
   return inner;
}

outer_t* a = z_alloc( sizeof (*outer), free_outer);


char* reused_string = z_strdup("hello");

a->i1 = inner_mk(reused_string);
a->i2 = inner_mk(reused_string);

//sometimes you want to override a method
a->i2->do_something = inner_do_something_boring;


z_free(reused_string); //don't need this anymore, we inner_mk addref'ed it

foo(a); //this calls the 'do_something' method on both i1 and i2


//sometime later, something else copies a reference to a:

a_copy = z_addref(a);
//
and then maybe the original a goes out of scope:

z_free(a);

//then eventually the copy goes out of scope:

z_free(a_copy);  

//now z->i1, z->i2 are freed, recursively freeing the last reference to 'reused_string' which is now eventually destroyed




   

C++ programmers tell me the above is crazy and I should have made C++ classes for inner and outer, and then used boost smart pointers.  At work I program how I'm supposed to program to get things done.  At home, I program for fun, whatever way I want.

Share this post


Link to post
Share on other sites

C++ programmers tell me the above is crazy and I should have made C++ classes for inner and outer, and then used boost smart pointers.  At work I program how I'm supposed to program to get things done.  At home, I program for fun, whatever way I want.

If you were programming in C++, I might say they have a point. But if you're programming in C then they're clearly crazy for such suggestions smile.png

But to add to the discussion, I think some of the people have made excellent points. I won't repeat everything. I've primarily found knowing assembly useful when debugging release applications (where I haven't been able to reproduce bugs in debug builds), which has been really helpful to me. It doesn't happen a lot, but when it does... well, somebody has to get their hands dirty. Edited by Cornstalks

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement