Aug 27, 2024

Assembly language MOV instruction

In a normal Windows/Linux environment, you have heard about moving data or files. What we do is copy data from a source location to a destination. The assembly MOV instruction is very similar to that. But actually, the assembly MOV instruction is equal to copy/paste. Because when we move a file, data will be removed from the source.

Even in a simple assembly program, we use the mov command many times. Source and destination can be a register, memory address, or any other place. Sometimes we copy a value from a stack to a register. At another time, we copy the value of each to ebp. For all of such tasks, we can use the mov instruction.

Syntax of the MOV Instruction

Since we use Intel's assembly syntax, the following is the format of the instruction:

mov [destination] [source]

(If you prefer using AT&T assembly syntax, you want to put the source first and destination second.)

Ok, let's see some examples of moving data from one place to another place.

mov eax, 0x1

This assembly instruction will copy the value 0x1 (0x1 is the hexadecimal representation of one) into the eax register. The above instruction directly copied a value to a place. So we call it direct mode or immediate mode.

mov eax, ebx

Can you think about what the above code does? It will copy whatever value is found at ebx to the eax register.

Here we can see a practical example of the above assembly instruction. I used the GDB debugger to demonstrate it.

(gdb) i r ebp esp
ebp 0xbffffd38 0xbffffd38
esp 0xbffffcb8 0xbffffcb8

First, I examined esp and ebp using the info register command in GDB to see what those registers hold. The esp register holds the value 0xbffffcb8, and ebp holds the value 0xbffffd38. If you're not familiar with GDB, please refer to our old tutorials on debugging binaries with GDB.

Next, I used x/i $eip to see the assembly instruction to be executed next. You can see that the instruction is mov ebp, esp. Well, you know what it is going to do. After that, I used the ni command (ni stands for next instruction) to execute that instruction on the CPU.

(gdb) x/i $eip
0x80483f5 : mov ebp,esp
(gdb) ni

Now, as we know, the CPU will copy whatever is found on esp to the ebp register. Let's see if it is true.

(gdb) i r ebp esp
ebp 0xbffffcb8 0xbffffcb8
esp 0xbffffcb8 0xbffffcb8

I used the info register command again to see what's on esp and ebp. You can see the esp register holds the value 0xbffffcb8. That's fine. It is the old value of esp. So the value of esp has not changed. What about ebp? It also holds the value 0xbffffcb8. So we can clearly see that the value of esp has been copied to ebp. Great. Now we saw it practically.

In the following image, you can see a layout of a 32-bit register.

structure-of-32-bit-register

Ok. Now you know how we can copy data from one register to another register. Let's give your focus on the following code line.

mov eax, [ebx]

If you pay attention closely, you may see that this code is not equal to the previous one. Here, the source location (ebx) is covered with brackets. What does it mean? Here we are not copying the value of ebx into eax. Instead, the ebx register acts as a pointer.

In C programming, you may have heard about pointers. Here, there is a memory address in the ebx register. We get that address and copy whatever is found at that memory address into the eax register.

The following instruction is very similar to the above one.

mov [ebx], eax

It takes the value from eax. Then, take the value from ebx and treat it as a memory address. Then go to that address and copy the value found at the eax register.

It's also possible to copy a direct value to a pointer location like the following.

mov [esp], 0x1

This will copy the value 0x1 into the location pointed by the value of esp. Here you can see it practically.

(gdb) i r esp
esp 0xbffffc50 0xbffffc50
(gdb) x/x 0xbffffc50
0xbffffc50: 0x080485e0

First, I examined the value of esp. It is 0xbffffc50. Now, we treat this as a memory address and check what is in that location. We can examine that by entering the command x/x 0xbffffc50. You can see there is a value 0x080485e0. Now we examine eip to check the next instruction and use the ni command to execute it on the CPU.

(gdb) x/i $eip
0x80484bc : mov [esp], 0x1
(gdb) ni

We saw the next instruction is mov [esp], 0x1. Now, as the theory goes, 0x1 should be copied to the location pointed by esp. Let's examine that location again to check it.

(gdb) i r esp
esp 0xbffffc50 0xbffffc50
(gdb) x/x 0xbffffc50
0xbffffc50: 0x00000001

Yes. All is going as expected. I think now you understood the concept of pointed locations. Now, what about the following example?

(gdb) i r esp eax
esp 0xbffffc50 0xbffffc50
eax 0xbffffc6c -1073742740
(gdb) x/x 0xbffffc50
0xbffffc50: 0x00000000
(gdb) x/i $eip
0x804844d : mov [esp], eax
(gdb) ni
(gdb) x/x 0xbffffc50
0xbffffc50: 0xbffffc6c

I don't go too deeply into explaining it. If you understood the previous one, you may realize what's going on here. It'll take the value of eax and copy it to the location pointed by the value of the esp register.

Can you understand what the following assembly instruction does?

mov eax, [esp+0x5c]

The concept is the same as mov eax, [esp]. But this time, we add a hexadecimal value to the value of the esp register. What does it mean? Read the following code and try to understand:

(gdb) i r esp eax
esp 0xbffffc50 0xbffffc50
eax 0x30 48
(gdb) x/x 0xbffffc50 + 0x5c
0xbffffcac: 0x66666666
(gdb) x/i $eip
0x8048471 : mov eax, [esp+0x5c]
(gdb) ni
(gdb) i r eax
eax 0x66666666 1717986918

When we execute mov eax, [esp+0x5c], the following happens:

  • First, we get the value of esp. It is 0xbffffc50.
  • Next, we add 0x5c to it. The answer is 0xbffffcac. You can use a calculator to do it.
  • Then, we treat this answer as a memory address and go to that location.
  • Finally, we copy whatever is found at that location and copy it to the eax register.

Let's take another example.

mov [eax], [ebx]

What happens here? First, we get the value of the ebx register. We treat it as a memory address. Let's call this address A. Next, we take the value from eax and treat that as a memory address. Let's call this address B. Now we copy whatever is found at address A into address B. Got it?

Finally, it's possible to do something like the following:

mov al, 0x1

This is a cool trick we often use in shell-coding. Here al is not actually a register. It is a section of the register. To understand this, refer to the following image:

single-32-bit-register-divided

Since we are talking about the 32-bit architecture, a CPU register is 32 bits in length. The least significant two bytes of eax are called the ax register. That is 16 bits long. That ax part can be divided into two parts as al and ah. You can learn more about this in our CPU registers tutorial.

So, guys, that's all for this document. I hope you learned something new. Thanks for reading.

ABOUT HACKSLAND

Explorer the world of cyber security. Read some cool articles on System exploitation, Web application hacking, exploit development, malwara analysis, Cryptography etc.

CATEGORIES
SOCIAL