Addition and Subtraction

The addition and subtraction instructions are add and sub. They take the general form of:

add/sub (destination), (source)

You can add registers to registers, registers to constants, and registers to the contents of memory. The size (in bits) of the source and destinations have to be the same. Both affect the flags of the system. For instance, if the result of a sub is zero, the zero flag is set. For example:

Multiplication and Division

The instructions for multiplication and division are mul and div. Both only operate on the accumulator register (eax) and use the data register (edx) as an overflow. The part of the registers affected are determined by the size of the operand.

The following diagram demonstrates how the accumulator and the data registers fit together when being used by the instructions.

Therefore, to get expected results, it is recommended that you set edx to zero before calling mul or div. For example:

Bitshift Operations

The instructions shl and shr shift the given register bits left and right by the given bit count. These are highly efficient, and should be preferred over the mul and div instructions for parameters that are powers of two. For example:

An Introduction to Assembly Language: Part III

Test Instructions/Loops

There are a number of instructions that can be used to test for particular conditions. These perform the same operations as an arithmetic operation but don't change the values in the registers; they just affect the flags.

The cmp instruction effectively subtracts the source from the destination, but doesn't save the resultant value. For instance:

The second is the .repeat - .until loop. There are various forms of this. .untilcxz decrements ecx by one and continues the loop if the result is not zero. .until zero? continues the loop until the zero flag is set.

Note that there is a comma between the function name and the first parameter.

Local Memory

MASM allows you to allocate memory local to functions and label it appropriately. This could potentially be considered as local variables, but if you examine the underlying machine language, you'll see that in fact it's just another shorthand form for accessing memory.

You define memory at the start of the function. If you examine the disassembly, you'll see that what actually happens is that a block of static memory is allocated before the first instruction in the function. The memory has a size that is determined by the basic types in MASM; in other words, BYTE, WORD, or DWORD.

Optimisation

When attempting to write efficient code,it must be considered that not every instruction takes the same time to complete. For instance, mul and div operations are relatively slow compared to the bit-shift operations of shr and shl. A full list of the times of each operation is available in the MASM help files.

When writing efficient code, another consideration is number of instructions involved inside of loops. The fewer the number of instructions, the faster the code will be.

When writing code, memory access is slower than access to registers, so always try to use registers in preference to local function memory.

Also, the efficiency of a jmp depends on the number of bytes to be jumped. This instruction takes offsets of either 8, 16, or 32 bits in size and an 8-bit jump is considerably more efficient than a 32-bit jump. This obviously affects loops: Loops whose instructions size is less than 128 bytes are more efficient than loops containing large blocks of code.

The primary concern is the algorithm itself. The fastest algorithms are always the simplest because they always contain the fewest number of instructions necessary. It is always better to reconsider the algorithm that you are using for a particular task, and if you can trade some accuracy or flexibility in favour of a large improvement in the speed, do so.

There are many, many other considerations when it comes to optimising assembler. Again, the MASM help files are an invaluable source for fine-tuning your code.

Conclusion

I hope that this set of tutorials has been interesting and informative. It is by no means complete because it is only intended as an introduction. For more information, consult the tutorials and help files that come with MASM.

But, I hope that I have demonstrated the fact that Assembler isn't difficult to write and you should be able to add considerable speed to your applications and perform tasks that you never thought possible in real time.

Top White Papers and Webcasts

When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.

U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.