Hi, I'm planning to learn assembly and was wondering what is the best way to go about developing a graphics/game app. I have about 3 years of c/c++ experience and am familiar with most 3d graphics apis. I have never written assembly before so wanted to learn by making a game. I am running on a 32bit windows on an x86 architecture.

What is the best assembler to learn for my purposes ? I looked into MASM but it felt like pseudo/high level assembly and I'm not sure if it will help me learn.
Does anyone have any recommendations ? I would prefer to use openGL/directX after a while to do my graphics but I'm not sure how those work at the assembly level.

Thanks
Posted on 2010-09-19 16:12:01 by Spidey
Hey :) I've written both DirectX and OpenGL stuff under MASM...
Despite appearances, MASM is perfectly capable of dealing with 100% lowlevel asm if you're that much of a masochist - and it's certainly been the assembler I've chosen for the past decade or so.
The highlevel directives in MASM are optional - and some other assemblers have been gravitating toward supporting exactly this kind of thing !!! Don't be so sure it's a bad idea... once you know what the assembled code for these directives looks like, you'll probably CHOOSE to use them.
I would indeed recommend MASM as a starting-point for someone with existing C/C++ experience, and especially the ObjAsm package for writing C++-compatible object-oriented code using MASM.
But you should also check out NASMX, which will be my next assembler (some of our users are actively developing this NASM fork with a view to supporting development of object-oriented code).
Posted on 2010-09-20 08:06:27 by Homer
Thanks for the reply Homer! That was really helpful. I am looking into both MASM and NASM to see which one I should pick, but am favoring MASM because of what you said :)

I had some more questions, since you have experience developing graphics programs in assembly:

How long does it take to write a decent 3d program in assembly ?
What is the most powerful/impressive app you have written in assembly graphics ?
Is it possible to write complete games in assembly or is it way too tedious ?
Do you have any images/videos of what you or others have done ?

Thanks!
Posted on 2010-09-20 23:07:01 by Spidey
How long does it take to write a decent 3d program in assembly ?

That very much depends on your ability and motivation, the quality of your header files (especially relates to DirectX since they are constantly updating their headers for C/C++, and trying to keep your asm headers up to date is almost impossible!! I got sick of trying, and for this reason as well as being tied to only Windows OS, I have finally gone back to OpenGL). It also depends on whether you employ existing code modules (ObjAsm has a fairly advanced app framework for both OGL/DX as well as a custom software renderer) - theoretically as little as a single day's coding session, or as long as you like to hit your head against a brick wall?

What is the most powerful/impressive app you have written in assembly graphics ?

Hard to answer, I've written so many - custom BSP generator with automatic portal placement, or maybe animated skinmesh demo with automatic generation of bounding volumes for each "bone"'s associated vertices for accurate collision detection / physical simulation would both be high on my list.

Is it possible to write complete games in assembly or is it way too tedious ?

Writing a complete game for 3D is tedious no matter what language you choose - with some experience you can write a 2D game in a weekend , completely in asm... 3D stuff is typically a lot more difficult for novices, even a simple game would take a couple of weeks minimum, even using existing objects.
A really decent game, with all the eye candy, usually takes a TEAM of C++ programmers 1 to 4 years to produce, development times for object-oriented asm are roughly the same (even by yourself, assuming that you source the artwork somewhere as creating art can be more tedious and time-consuming than the actual coding)... for lowlevel asm, forget it - it will take you a decade, and by the time its finished, your software will be "ancient" !!!

Do you have any images/videos of what you or others have done ?

Sure, I've posted a bunch of screen shots and executable demos and sourcecode over the years, much of it right here on this forum, you can use the board's search facility, and also much of it appears in top google search results for various related terms like "asm physics" or "homer skinmesh" ;)
You'll find I'm also responsible for much of ObjAsm's related code.
However I've been involved far more in developing various components of a game engine (such as neural network-based AI for game critters) than I have with the "eye candy" - I would suggest that Scali knows a lot more about the more recent advances in graphics hardware programming than myself.
I learned a lot from a guy called Scronty, you might still find his tutorials and other examples online, however it's been a couple of years since he was a regular around here.


Posted on 2010-09-21 01:53:32 by Homer
Thanks for the great reply again Homer. Well, thats motivation enough for me to learn assembly and make something cool. I'll most probably go with MASM and OpenGL using ObjAsm. I noticed you have some great tutorials on that as well :) But I'll start with raw assembly first and then move on to the more advanced packages. This way I'll atleast know how they work. I've written tons of 2d/3d games in c/c++, but not even a single line in assembly, so now I'll try rewriting the simpler games I wrote, in assembly. Thanks for the info.

I did have one last question though; from what you said, it sounds like for a person experienced in both c++ and assembly, the development times for a complex app/game will be about the same ? I've always heard that assembly takes alot more work. But I'm guessing you are talking about higher level assemblers like MASM ? So, what I'm asking is, that for someone who is equally skilled in assembly and c++, is it possible to write the same quality app in about the same time ? and if you had to pick one, what would you pick and why ?  Thanks!
Posted on 2010-09-21 02:25:11 by Spidey
My advice would be to start with inline asm, if you want to convert C++ code to assembly.
Or perhaps by rewriting certain functions in assembly, and putting them in separate modules, linking them to the C++ code.

I think some of the most tedious stuff in assembly is interacting with the graphics API (the aforementioned header issues, especially with DirectX and its COM buildup, complex types and all that). It is also the least interesting. After all, an API call is an API call. You pass the same parameters, and the same code is executed inside the function. After you've figured out how to call a function from assembly, there's little more to learn... and there's no benefits from calling them from assembly.

The real assembly programming is not in calling API functions, but in performing actual mathematics. Especially floating point/SIMD code may take a while to adjust to in assembly.
And that's also where assembly can shine, with more efficient code.

In general I'd say that assembly takes longer to write, no matter how good you are.
Since you are working at a lower abstraction level, there is more that can go wrong. We are human, we are not infallible, so it may happen that you accidentally use the wrong register here or there, or forgot to do something or other. So sometimes you'll spend more time chasing bugs.

Another thing is about refactoring. Again, we're human, we generally don't get everything right the first time. So if you decide that you may want to design something a bit different in order to do something you didn't think of at first... it's generally easier to rewrite C++ code than it is to rewrite the assembly equivalent (again because you need to pay more attention to small details like calling conventions, registers etc).
Posted on 2010-09-21 04:13:09 by Scali

I would agree with the above comments, this is all absolutely correct !!
However I would like to clarify one point of contention, which is about that new thing called "oopasm".

Object-oriented assembly language is essentially C++ that builds on an assembler instead of a compiler.
It even looks similar, from a distance... certainly it does not resemble asm enough to call it 'pure asm', but under the hood, it is indeed pure asm - and you can LOOK under the hood, it's all there in sourcecode form, every last part of it.

The development times are similar, because the language is similar...
I did not say that the dev times are equivalent - but oopasm certainly closes the gap considerably, as you no longer need to "reinvent the wheel", you have access to a large codebase of hand-optimized and already-debugged functions, you can use polymorphism and inheritance to develop new variants of existing classes, etc.. most of the benefits of C/C++ are at your disposal, although there are certainly a few fundamental differences, some good and some bad, depending completely on your point of view.

I mentioned ObjAsm early because it can help you to ease your way into asm without having to completely learn asm at its lowest level with no prior experience.

Yes, asm development times will always be greater than a HLL like for example Java, and a lot of people like to hate me for squarely sitting on the fence between highlevel and lowlevel code - the asm zealots think I am a sell-out for even considering that asm should evolve into a more modern variant, the C++ guys can't stand the idea that asm still exists at ALL, and both groups consider what we're doing to be some kind of weird alien hybrid which should be killed off.. personally I believe that if both groups feel so strongly about this language without ever having tried it, then maybe they feel threatened, and maybe we're onto something good.

Nonetheless, Scali is also right about playing with inline asm in C languages - noting that inline asm is not nearly as powerful as macro asm, it's a great place to start learning about using registers, learning the most common opcodes, and optimizing existing functions (especially those involving loops, or heavy math).

Posted on 2010-09-21 05:13:31 by Homer
I'd like to clarify that I made the above comments while taking powerful assembly toolkits such as ObjAsm into full consideration.
If you bother to go back in history, you'll find that one of the first examples of using DirectX from assembly is a DirectDraw plasma example by Ewald and X-Calibre... X-Calibre being me (my nickname morphed into Scali over time).
You will find that this early attempt already did a lot of the groundwork with macros for COM datatypes, vtables, extended invoke macros and whatnot, very similar to what you see today with OOP asm toolkits.

I suppose I'm in a similar position to Homer, somewhere in between assembly and HLL. Although I have to admit, apart from this plasma example, I haven't really done any full assembly DirectX or OpenGL applications. My code is either hybrid (MASM modules or inline assembly) or completely HLL.
Posted on 2010-09-21 05:52:37 by Scali
Thanks a lot guys! this was all really helpful. The first thing I had planned was actually to just write regular c functions and view them in the disassembler, but then I thought I'd learn more if I wrote programs from ground up. I think I'll do both now. Thanks for the info on graphics Scali. I guess you are right, Api calls will just be API calls and I won't really learn much assembly from that.

I looked into ObjAsm and OOAsm in general. Its a quite amazing concept, and I had no idea such a thing even existed before this post. Thanks for telling me about it. I wont get it into write now because like I said, I want to learn raw assembly. But once I'm confident in that, I'll definitely look into objAsm32 and maybe write some fun graphics apps etc since it won't be much different than cpp anyway.

Thanks a lot guys! This was really insightful!
Posted on 2010-09-22 02:13:33 by Spidey
Modern C/C++ compilers can come close to the efficacy of asm, but they can never and will never be as good at optimizing code as a human - this is the number one reason that asm exists to this day, if we ignore things like "self modifying code" that is simply not practical in higher languages.

When you write asm, you decide exactly what registers get used for what purpose, and you have a good idea of which registers contain critical values and which don't, so you can reassign registers for new purposes without simply preserving them for no reason, etc.

I have been VERY disappointed by looking at the disassembly of some common Microsoft code for example the D3DXMatrixIdentity api function, which has to store the value 1.0 in four cells of an array, and 0.0 in all the others.. guess what it does? It loads zero, stores zero, loads zero, stores zero... ugh!

You'll get the full picture before too long ;)
Posted on 2010-09-22 05:13:27 by Homer