Basic Operations and Registers in Assembly

You are reading the second segment of a multi-part series covering beginner assembly programming in Visual C IDE. Today we are going to learn about some basic registers and investigate the most common instructions. We are going to write lines of code that solve a polynomial equation. The purpose of this article is to help you get familiar with coding in ASM. We are preparing for something more advanced later on.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 3
July 06, 2010
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

The previous part of this series was an introduction to the world of machine code and assembly programming. We got to know how assembly code looks, what compilers are, and why we need them. Based on the various options, we've picked the Visual C/C++ IDE, which is part of the Visual Studio suite, regardless of which version (at least 6.0 is preferred, though).

This article requires almost zero coding experience, but it is recommended that you be at least familiar with the act of programming and how to build some basic apps in C/C++. We will instill our ASM code as part of a traditional C code. Assembly background is not required, but it is advised that you check the first part of this series if you've missed it.

All of this having been said, let's get down to the real work: registers? What are they?!

Registers in Assembly

It may sound like we're jumping right into the middle of a computer architecture course, but registers are the "storage" places that are closest to the processor. They are situated on the top of the memory hierarchy. The CPU can access registers faster than other memory locations, such as cache, RAM, or hard drives, obviously.

There are two kinds of registers: general-purpose registers and special-purpose registers. Their count is limited; we can't have thousands of registers. We should note that the general-purpose registers usually have their "dedicated" purposes, but they cannot be used just for those tasks. Mainly this means that some instructions have better efficiency (since they are optimized) to work if we use their "best fit" registers, but will work with other registers as well. An example of this is the division (EAX and EDX).

Let's enumerate the general-purpose registers:

  • EAX - the accumulator
  • EBX - base index, in the case of arrays.
  • ECX - counter register.
  • EDX - data ESI - source index, especially in the case of string operations.
  • EDI - destination index, same as above-string operations.

And now the special-purpose registers (these are for further reference):

  • ESP - register pointing to the address of the top element of the stack.
  • EBP - pointing to the bottom element's address of the stack.
  • EIP - instruction registers; it contains the program counter.

Generally, we are always grabbing values from the memory; placing them into registers; accomplishing what is meant to be done, such as multiplications, additions, comparisons, jumps, who knows what else; and then, finally moving them back into the memory locations (variables). Registers are just places where the main action happens.

This is just barely sufficient for you to know in order to work on a basic level with registers. The previous article also gave a sense of how computers work and why  ASM code is important. In a future article in this series we will also investigate flags and see their purpose, but for right now, those four general-purpose registers (EAX through EDX) are plenty.

Basic Operations

Now that we've learned about registers, let's present some basic operations. The most basic operations are adding and multiplying numbers.

Given is the following polynomial equation: a*x^3 + b*x^2 + c*x + d.

We will create a code sample that solves this equation in both traditional C and ASM. Then we can compare the results and see for ourselves that they indeed yield the same results. The code snippet will exemplify some basic assembly operations, such as the multiplying (MUL) and adding (ADD) numbers. Moving is also necessary (MOV).

The entire program is below. Please check it out. We read the values of "a," "b," "c," "d," and "x" from the keyboard (user input), and we print out the results to the screen. Right after the snippet we will explain the use of registers, and explain the code line-by-line.

#include<stdio.h>

 

int main()

{

   int a,b,c,d,x,fx,gx;

   scanf("%d%d%d%d%d",&a,&b,&c,&d,&x);

   fx=a*x*x*x+b*x*x+c*x+d;

 

   __asm

   {

      mov EAX,0

      mov gx,EAX

      mov EAX,x

      mul x

      mul x

      mul a

      add gx,EAX

      mov EAX,x

      mul x

      mul b

      add gx,EAX

      mov EAX,c

      mul x

      add gx,EAX

      mov EAX,d

      add gx,EAX

   }

   printf("%d n %d n",gx,fx);

}

The first part of the code until the __asm code block should make sense. Now the assembly part implements basic concepts of assembly language programming. At first, we are working with the EAX register. We set its value to zero in order to clean up some possible leftovers (if there are any). Think of it as emptying a garbage can.

Excuse the term, I've yet to hear anyone comparing registers to garbage cans... Anyway, the command that places the value zero into the EAX register is MOV. The next line of code places the content of EAX into the  variable called "gx," which is technically zero. So at this time, "gx" equals EAX and they contain zero. We will gradually add up the result of the function in gx, from left to right. So first we do the a*x^3 part.

Moving on, we place the value of "x" into EAX, and multiply that with "x;" then again; and then again, but with the value of the variable "a." At this time the EAX register equals a*x*x*x.

Remember, at the beginning we reset the value of "gx" to zero. This means we can add EAX to "gx." Now we move "x" to EAX and multiply it with "x," and then with "b." Now EAX equals b*x*x. We add EAX to "gx" (that contains the left-most part of the polynomial equation). At this time "gx" equals a*x^3 + b*x^2.

As our final steps, we move "c" into EAX so we can work with it. We multiply the value with "x." This yields the c*x. We add this value into "gx." I think anyone can guess that the polynomial equation is almost done; the only part missing is the "d" from the end.

In order to do this, we move "d" into EAX and add EAX to the "gx."

Let's execute the application. We'll enter the following values: a=1, b=3, c=2, d=5, and x=3. This way we calculate the polynomial equation x^3+3*x^2 + 2*x + 5, where x is given as "3." The output is 65 via both C code and ASM code. Obviously. :)                              

 

And it's done! There are easier and much shorter ways to do this. This code sample's only purpose was to give a sense of how to build assembly programs on a line-by-line basis, how to think sequentially, and work with registers. We started moving them around, mixing in the cocktail of programming some basic operations, and finally ended up with some foundation of ASM coding. This prepared us for something more advanced.

More Instructions

Let's talk about more instructions here that work in a similar fashion. First of all, MUL deals with multiplying, just like DIV deals with division. These are for unsigned quantities (=values), while IMUL and IDIV are for signed operations.

It should be noted that if the operand is 16-bit, when it's multiplied by AX (in this case it's not EAX), the results must be stored in 32-bit; as such, it ends up placed into DX:AX. Remember, this is when we're working on 16-bit systems. However, these days are long gone, and what matters to us right now is that in the case of 32-bit multiplications, the operand is multiplied with EAX (32-bit), and the result is 64-bit-it's stored in EDX:EAX.

The reason for the above is that multiplication can lead to "larger" numbers than the operand itself, and we must be able to find a way to store the result. In the  case of division it's slightly easier; the results are always stored like this: quotient placed in EAX (or AX), while the remainderis put in EDX (DX).

All right, now let's enumerate some other instructions. Just like MOV, most moving and other operations that deal with a destination and source operands share the same syntax, such as: "MOV dest, src." This means that the first operand is always going to be the destination register while the latter is the source. XCHG is another instruction that works like this. It swaps destination with source. An example: XCHG dest, src.

ADD was the arithmetic operation we already used (it also works based on the destination, source fashion). It has another form: ADC. This means add with carry, which is a flag; we will talk about flags later on. SUB deals with subtraction. An example: "SUB dest, source"-which stands for: dest=dest-source. Its other form is the SBB, subtraction with borrow flag. XADD is an addition operation, but it first exchanges the registers, then adds the registers in a similar fashion.

Two more easy operations are INC and DEC. These only have one operand; they deal with increment and decrement, respectively. Their syntax is like this: "INC something." In the C/C++ programming language this represents: ++something.

Okay, that's enough about instructions. Thanks for reading this part of the series. The basic foundation of our ASM coding experience is already set. Practice makes perfect. Over the following articles, we will always advance one step at a time, learning more.

Taking a Break

Don't forget to tune in for the next segments of this series. The following article will discuss loops and labels. We're going to make structures that work similarly to FOR and DO-WHILE loops. We also need to understand how compare instructions work; after that, building if-then-else constructs becomes child's play. We compare and then jump away!

In order to illustrate what we're learning, we'll put everything into practice by creating a small program that checks whether a number is prime or not. We'll then expand that code into an application that counts the primes up to 10,000.

Moving on, the fourth and fifth articles of the series will each cover more coding techniques and basic operations, such as stacks and functions, respectively. The final part will demonstrate how to write a program that generates the Fibonacci sequence using everything we've learned until that point.

We will also learn how to measure the time of execution of lines of code in order to investigate whether a piece of code runs faster when written in traditional C or ASM. It should not surprise anyone that in the real world, there will rarely be any times, if ever, where we are required to write code from scratch in assembly. Assembly is used mostly when higher-level coding languages don't offer that kind of performance enhancement.

Therefore, if my series has sparked some interest in assembly programming, it is mandatory that you understand how to check code performance. This is how we will know when it is worthwhile to implement assembly code in our application. So stick around!

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.

blog comments powered by Disqus
BRAINDUMP ARTICLES

- Microsoft Windows 8 Committed to Cloud Compu...
- Independent Developers Favor Windows Phone 7
- Dell Introduces VMware-based Cloud
- Microsoft and Skype Agree to Acquisition Deal
- Transfer Contacts in Microsoft Outlook
- Zune`s Next Steps
- Safari Books Online Review
- Does Microsoft Get Touch Screens Now?
- Microsoft`s Record Quarterly Earnings Not En...
- Basic Operations and Registers in Assembly
- Assembly Coding within Visual C/C++ IDE
- New Microsoft Office Coming with a Twist
- Microsoft`s FUSE Labs Unveils Spindex Social...
- HP Slate with Windows 7: Dead or Alive?
- Windows Phone 7 Mobile OS to Rival Android a...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 7 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials