HomeBrainDump Assembly Coding within Visual C/C++ IDE
Assembly Coding within Visual C/C++ IDE
When it comes to low-level languages such as Assembly, most people think that it is something unimaginably hard to learn. It is not a black art. ASM is a programming language just like any other; the main difference is that it is the closest to the machine's own language. As such, it’s slightly harder to master, requires practice and at least a sense of knowing what happens behind the scenes (architecture).
Starting today, we are going to feature a multi-part series (5+) on beginner-level ASM coding. We will start with the basics and then advance up to an intermediate level. The main purpose of the series is to give you an idea of what’s possible with ASM, and try to make it understandable as you think of ASM lines of code. They don’t bite, really.
Higher level programming languages are designed in such a way as to help software developers the most and to make industrial coding as fast and easy as possible. This means coders are creating applications on a conveyor belt. The syntax of those languages “makes sense;” one line of code in them sometimes stand for more than one line of ASM code.
Assembly is a low-level programming language, and the commands and registers (memory locations) are replaced by sequences of the latter. Other than that, it is pretty much the same as the machine code (which is nothing but numbers!). In ASM there are short, few-letter words to help with memorization of instructions and specific other items. This way, it is definitely a bit more human-friendly than machine code per se.
Programming in assembly does not require an IDE by itself. The code can and should be written in simple text files. However, it needs to be “assembled.” This is made possible via various tools and depends on operating systems, computer architectures, etc. It should be also noted that there is no “universal” ASM syntax for everything. Different CPU architectures have their own slightly altered ASM syntax and semantics.
Nevertheless, while we think of the big picture, right now this tutorial will cover how to code in ASM on the Windows operating systems and general personal computers. When the time comes to design code for a Fujitsu microcontroller, for example, you will already know how to start and you can spend time researching the official documentation. But if you have no idea what assembly is about, the documentation is pretty much worthless.
In this series we are going to use the Visual Studio C IDE. Any version should work fine, but it s recommended that you use at least 6.0, if not 2003-2005, or even 2008 (or 2010). The higher, the better; but whichever one you are familiar with should suffice. It is a common IDE, and if you are visiting ASP Free, where we quite frequently feature Win32 coding, it is a sure-fire assumption that you have a copy. If not, subscribe for the latest beta!
Now that we know what to expect, let’s try to lay some ground work for the series.
As mentioned earlier, we are going to write traditional C/C++ code where we mix in our ASM lines of code. The IDE is Visual Studio. We start a new “empty project” that is C. At least beginner-level of C programming knowledge is appreciated, but it is not mandatory. You just need diligence. Throughout this series we will every so often compare our ASM code with their C counterparts to illustrate specific ideas.
First of all, we need to learn how to write comments in ASM. It is quite a difficult language, since the mnemonics of instructions don’t always speak for themselves. When jumps and labels are implemented as well, following through can be frustrating. In C/C++ we know that commenting can be done with “//” (one-liner) or “/*” and “*/” when delineating multiple lines of comments. In ASM we can do this “;”.
The next thing we need to know is how the hell are we going to mix ASM code into C?
Consider the following code snippet:
#include<stdio.h>
int main()
{
printf(“this is code written in traditional c”);
__asm
{
; this is where we write our ASM code
}
return 0;
}
As you can see, there is a block delineated by { }’s that starts with __asm. That is how we make it obvious for the C compiler to assemble that segment and not to compile anymore. It has nothing to do with the C compiler; code is ignored. It goes through a linking and translating phase only when the ready-to-run code is translated to machine language. First our C code gets compiled to ASM itself, too.
Assembly code stands for the following three types of instruction statements:
opcode mnemonics: instructions with their operands (if there are any);
data section: define data sections (type, length, location, direction, etc.);
assembly directives: these are ignored by the assembler when translating to machine code, just like C directives are written “for” the C compiler.
As we will find out throughout this series, our main priority lies in understanding how to work with ASM code, especially when used for optimization tasks! We won’t focus on creating entire applications from scratch purely with ASM code. The preliminary tasks we will always accomplish in C—such as reading input, printing output, etc.
All right, but let’s investigate current uses of assembly coding. Turn the page!
Earlier in this article we mentioned that higher-level programming languages were invented to make routine programming tasks easier, faster, more understandable, practical, industrial, and viable. Yes, these all make sense, but then why do we need to know and (when to use, if we decide to) learn ASM coding?
Well, it’s not mandatory to know assembly. Any of us could be within the top-paid coders of the world without mastering assembly. As of late, compilers are highly optimized, and the processing capabilities of our systems have also increased. Because of this, there is lots of waste and unoptimized code that breezes through nowadays in “bloated” applications. Memory leaks are ignored, they’re paged, no one cares...
Assembly coding is useful when we want to interact directly with hardware (device drivers, interrupts, etc.). It's good when we're using direct CPU processor (or microcontroller) –specific instructions that are available otherwise via compilers. We may want to use it with embedded systems where extreme optimization is required, and we also have severe resource constraints. It also helps when we're designing self-modifying code, instruction set simulators, or other close to hardware applications that react “similarly” to boot-loaders, viruses, or drivers for devices.
Other than these, assembly is also helpful when we are planning to debug or trace snippets of code that were reverse engineered. That is to say, we don’t have access to the source code (in distributed form) of some libraries/applications, but then we sort of reverse engineer and get the translated machine code into ASM, which can be carefully examined and understood if we have tons of patience and experience already.
Therefore, in a future part of this series we will investigate how we can measure the time it takes for an instruction to be executed. Then we can compare the time it takes to do something when accomplished in traditional C and see how much faster (or longer) it takes to do the same in assembly.
Sometimes the results will be shocking, since compilers are already highly optimized. And sometimes doing the same thing in assembly might take few dozen lines of code—and we achieve the same result with only one line in a high-level language. But there are cases when a high-level language would inefficiently manage memory or go through countless unnecessary operations. For these times, ASM is a better choice. But we cannot know this if we don’t use performance evaluation functions.
It’s time to sum up this introduction article. The second part of the series will contain a great deal of new stuff. We’re going to make our very first application in ASM that can be executed and will have an output! Get ready!
In this first article of the assembly language coding series, we got to know the development environment (IDE), what assembly code is, and finally understood how to think when planning to write ASM code.
There will rarely be times when we’re required to write assembly code from scratch for an entire full-blown application. Rather, we need to know when it is worthwhile to implement a few lines of code in order to speed up the execution time, do some arithmetic or other operation more efficiently and so forth. We detailed some uses on the previous page.
The further segments of this multi-part series will give you an introduction to ASM coding. We will start with understanding what registers are and how to do basic operations such as addition, multiplying, and comparisons with them. Once we know that, we can move further and create looping structures, work with labels, and do jumps. Then we are going to create little apps that implement functions, generate the Fibonacci series, and such.
Therefore, don’t forget to tune in for the next part! Always here on ASP Free!
In closing, I’d like to invite you to join our community of technology professionals experienced in all areas of IT&C starting from software and hardware up to consumer electronics at Dev Hardware forums. Also, be sure to check out the community of our sister site at Dev Shed Forums . We are friendly and we’ll do our best to help you.