How expensive is that x86 instruction?[Part — I]

RIXED LABS
5 min readAug 27, 2022

--

Hello people, I hope everyone is doing great. It has been a lot of days since I wrote a blog on any of the topics. So, I decided to write a small blog on something which I learnt that is micro operations or μop. So let us get started without any further delay.

Contents

  • 0x00: How & Why Micro Operations?
  • 0x01: What exactly are Micro Operations(Part-I)
  • 0x02: Time for some basics
  • 0x03: What exactly are Micro Operations(Part-II)
  • 0x04: Writing a small C program & explaining how expensive it is.
  • 0x05: Resources & Credits.

0x00: How & Why Micro Operations?

First of all to be honest, I do not consider myself a low level programming connoisseur, so every time I come across any assembly tutorial independent of any processor be it ARM, Intel, Power-PC I take out some time to read in the hope of learning something new every-time. And this time luckily I came across this tutorial which focuses on understanding Windows x64 Assembly. As, we all love to learn something new everyday, I would suggest you to dive into this article, you will definitely love it. Anyways enough of introduction, so this time I came across this term known as micro-operations or μop, this topic sounded pretty new to me and I never took out time to read through it. Although there is a brief description present at the tutorial itself, I decided to understand this through a beginner’s prospective, so this entire blog will be focused on the understanding of micro operations.

0x01: What exactly are micro-operations (Part-I)?

According to the tutorial, A micro-operation, or μop, is one way we use to measure how expensive an assembly pseudo-operation is. These are decoded instructions from the higher-level macro-operations (i.e. our add, mul, cmp instructions) that tell the CPU what exactly to execute in terms of micro-operations.

Alright, cool! But what exactly is a macro-operation even 😕, and how is the term “expensive” related to “assembly-pseudo” operation and last but not the least what exactly is “higher-level macro operations” referred to here? Okay, time for some little basics this time.

0x02: Time for some basics

The very first thing in the section which has to be explained is how that simple looking hello world program or that calculator which most of us programmed in our early learning days be it any language gets converted to macro-operations and what they actually are?

So, when we write a simple “Hello World” program in C.

#include<stdio.h>int main(){puts("Hello World");return 0;}

So, after this simple program is written, we compile it using a compiler, let’s assume we are using gcc here, so the syntax would be gcc hello-world.c -o hello-world.exe where hello-world.c is the name of the source file and -o is a flag and hello-world.exe is the desired executable name.

After compiler takes up this source code, it performs a lot of operations like lexical analysis & syntax analysis, Intermediate level code generation and lot of optimizations take place, as this blog wont focus much on compiler internals, we would avoid describing each operation done by a compiler,

Image Source

then after all of these we have an object file. The object file is basically a file with .o extension which can if examined using tools dumpbin one can view assembly instructions or the one we are referring to here as macro-operations.

So, further this hello-world.obj can be linked with a linker which finally generates the final executable . An in-depth understanding of linker can be found here. After generating the disassembly we now have some understanding of macro-operations , now the other thing which comes to play is are these macro-operations different on all processors, an important term which is to be discussed is the ISA or Instruction Set Architecture, all these macro-operations are also known as instructions which is a part of the Instruction Set Architecture, this link contains the list of instructions for various operations.

As, previously said the ISA of each and every processor is different, the conditions on which it can be differentiated are :

  • Operand Storage in the CPU — Where are the operands kept other than in memory?
  • Number of explicit named operands — How many operands are named in a typical instruction.
  • Operand location — Can any ALU instruction operand be located in memory? Or must all operands be kept internally in the CPU?
  • Operations — What operations are provided in the ISA.
  • Type and size of operands — What is the type and size of each operand and how is it specified?

So, now after understanding about macro-operations and how they are different, let us move ahead understanding how are these macro-operations simplified further.

Let us take an instruction from the above image for explanation:

0000002E: add esp, 4

Source: Wikipedia

At the very beginning, the macro-operation or instruction is being held by the program counter, and then inside memory address register, then the instruction is copied to memory data register, then the program counter is increased by +1 i.e., as the address of the next instruction is to be loaded into the program counter. This entire thing can be summed up into Fetching of an instruction.

After the instruction is fetched, the decoding of an instruction takes place.

Then after the decoding and fetching is being done, the instruction is executed.

This can be summed up into Fetch-Decode-Execute cycle.

We finally are now comfortable with macro-operations and how are they simplified, but there stays a visible confusion. Why is the content passed on from Memory Address register to Memory Data Register? 😕

The explanation can be simplified as follows:

The process fetches instructions from memory and interprets them. Since the actions required to fetch an instruction and to fetch a data word are identical, the process encapsulates them in a procedure, read_memory. The procedure copies the address from the memory address register to the address bus, sets the read signal to ‘1’, then activates the request signal. When the memory responds, the procedure copies the data from the data bus signal to the memory data register and acknowledges to the memory by setting the request signal back to ‘0’. When the memory has completed its operation, the procedure returns. [ Cited from this source ]

So, finally we are done with some basics which will helped us to understand what are macro-operations and how are they executed, let us move ahead to the second part of micro-operations.

0x03: What exactly are Micro Operations(Part-II)

0x05: Resources & Credits

--

--