Hi Everyone,

I was away for so long and reason is as well “My Procrastination”. No matter how much I try to overcome this habit, I gets me all the time. Also job related things too and family and list goes on!!! Anyways, back to work…….

Sorry to say this, but this will be theory blog. Reason??? Because I did not cover everything in previous theory blogs and its impossible to cover all the theory in single blog. And even if I do that, you’ll not read that complete blog. Worse, you’ll never read my blogs again!!! 😀

Anyways you can expect theory blogs time-to-time . For now, we will look into some basic operations, such as: Data Movement, Arithmetic operations, String operations, Logical operations.

Pre-requisite:

Before checking the above-mentioned operations, first we need to understand the data types and data representation in x86 architecture. I’m not going to spend more words on this, but simple table:

#

Data Type

No of Bits

1Byte8
2Word16
3Double Word32
4Quad Word64
5Double Quad Word128

Declaring Initialized Data: DB, DW, DD, DQ, DT, DO and DY are used, much as in MASM, to declare initialized data in the output file. They can be invoked in a wide range of ways:

If you remember these variables will be part of .data section.

Uninitialized Data variables: resb and resw are instructions for declaring uninitialized data in code.

If you remember, these variables are part of .bss section.

Endianness: This is basically the sequence in which large numerical values get stored in memory. You can understand this with below representation:

IA-32 architecture uses Little Endian format.

I guess this much prerequisite is sufficient. Now to minimize theory we will write simple programs and analyse then in GDB to understand how above operation works. Let’s write these codes one by one:

In this code, I have taken example from NASM manual and put into simple exit code. So once run, program will gracefully exit. Now we will load the assembled executable binary of code in GDB for more inspection. Then let’s start.

(Executable Loaded in GDB with Breakpoint set to “_start” symbol. “r” for starting execution of code)

First, we will list out all the variables present in the code with “info variables” command.

To examine contents of variables and registers, “x” command is used in GDB. “help x” command will show following output.

Now based on above screenshot, you can understand below screenshots.

You can observe that I have tried couple of options here. You also have to do trial and error to get intended output. Same goes with next screenshot.

You must try this all by yourself. That’s the only way to learn… Anyways, I hope this is sufficient to help you understand how to use x command. Hence lets move our focus to main part of blog….

Data Movement instructions:

Data movement instructions are used to move data between Register to Memory, Memory to Register, Register to Register. They are most common instructions in any assembly language code. We are going to look into few important data movement instructions. Let me remind you the important thing: Depending on your underlying processor each of this instruction may have different variants. To get details about them, you must get instruction manual provided by Intel on their website. You can get all necessary details in the instruction manual.

(Note: For ease of operation, I have installed PEDA in my VM. Feel free to use it you lazy a$5!!! You can find PEDA at GitHub. Feel free to use it, it’s amazing!!!)

  1. MOV Instruction: Used for moving data from Register to register, Mem to Register, segment to register, immediate value to register.
  2. XCHG Instruction: This instruction is used for swapping the contents of the registers. This can happen between two GPRs or GPR and memory location.
  3. LEA Instruction: LEA stands for Load Effective Address. This instruction will calculate effective address of source operand and save it into destination operand. Source operand can be 16/32 bit. This is limited to registers only.
  4. PUSH Instruction: PUSH instruction pushes content of source operand to stack. ESP is updated accordingly. PUSH has variant such as PUSHA (Pushes value of all registers to stack) and PUSHAD (Pushes values of important registers to stack)
  5. POP Instruction: POP is exactly opposite of PUSH. In this, content of STACK is moved to destination operand (GPR generally). ESP is adjusted accordingly. Its has variant such as POPA, POPAD.

Here is the simple program I have written to cover basic data movement instructions:

Now let’s assemble and link this code:

Simply running, executable will simply exit as there is nothing to display. Hence to see the commands in action, we will use GDB. Well, GDB equipped with PEDA. To execute, simply execute:

next setup breakpoint and run program as usual. Once that done, you can see following screen:

Beautiful and Neat, isn’t it? Since, this screenshot is pretty intuitive, I’m not going to explain this. READ IT YOURSELF!!!!!!!!!

Now we will execute this program step by step, using stepi instruction.

Now we will look into moving data from register to memory location. If you read code first, value stored in MSG string is 0xddccbbaa. Once we execute mov from register to memory you can see following:

Very intuitive right!!! for next two instruction same thing will happen. With this, MOV instruction is completed.

Next is XCHG instruction. Very straight forward instruction.

Now lets execute stepi.

With this xchg completed. Up next will be LEA. First screenshot is Effective address of memory loaded into register.

Next screenshot is effective address of register loaded in register.

LEA reg to reg

Then there is PUSH.

Lets go for another PUSH

Finally there is POP.

After second POP, stack returns to original position.

Finally, there is graceful exit code to exit out execution normally. And it ends. I hope you have understood basic data movement instructions.

Arithmetic Operations:

Note: Arithmetic instructions affect EFLAGs quite often. We need to be aware of those while executing these instructions.

  • ADD: Arithmetic addition. This can be Immediate operand added to register/memory (8/16/32 bit), sign extended immediate operand to register (16/32 bit), register to register/memory (8/16/32 bits), register/memory to register (8/16/32 bit). The OF, SF, ZF, AF, CF, and PF flags are set according to the result.
  • SUB: Arithmetic subtraction. Exactly same as that of ADD. Just replace addition with subtraction. 😛
  • MUL: Arithmetic multiplication. In this, multiplication happens on AL/AX/EAX. Result get stored in AX/DX+AX/EDX+EAX. OF and CF are set if upper half result is non-zero.
  • DIV: Arithmetic division. Exactly reverse of MUL. We will see in example.
  • INC: Arithmetic increment. Increases value of operand by 1. OF, CF flags affected.
  • Dec: Arithmetic decrement. Decreases value of operand by 1. OF, CF flags affected.
  • CLC: Clears Carry flag. CF=0
  • STC: Sets Carry flag. CF=1
  • CMC: Complements Carry Flag. Flips status of Carry flag.

I’ve copied simple code with limited options. You can try rest of the options.

Just like earlier, we will assemble-link this code. After that we will fire executable in GDB. Only difference now will be lot less screenshots. 😀

First we will perform ADD operation. For sake of convenience, I have skipped couple of STEPI commands. I hope you understand my pain. :'(

Well, First we set EAX = 0, then add 0x33 and 0x11 to it. Result: EAX = 0x44

Now we will skip to imm32 instruction. In this Values will be stored in CF-EAX combination.

You’ll observe similar results with Memory operations. You can check them by yourself.

Next we will see CLC, STC, CMC instructions.

Next instruction will clear carry flag.

Next instruction will set Carry again.

Next instruction will complement the current state of CARRY flag.

Now we will see couple of “Add with Carry” instructions. So first STC is required.

Now ADC will put 0x23 (imm 0x22 + carry 1) in EAX.

You can observe similar things with imm16 and imm32 operands. Exactly similar results will be found with SUB/SBB commands. TRY THEM YOURSELF!!!!

Next up is MUL. We will just see MUL imm8 instruction.

You can try other variants. Next is DIV. We will only consider imm8 division of Even number.

Here result stored only in EAX. Next we will see division of ODD number.

Result will be stored in EDX and EAX.

Honestly there are tonnes of variations with these commands. Kindly look into Intel Manuals and practice them yourself.

Now looking at all the blog I have written till now, it is more than 20 pages. And I’m feeling really groggy here. SO I’ll continue remaining instructions in next blogpost.

Leave a Reply