WEBVTT

00:00.450 --> 00:04.590
Hello, my name is Stephan, and in this lecture we will learn about the instruction types and we will

00:04.590 --> 00:05.940
also analyze this code.

00:05.940 --> 00:11.220
And in computer programming we use instructions to tell the computer what to do.

00:11.580 --> 00:15.090
Two important instructions mentioned here are L.

00:16.390 --> 00:22.540
A a load effective address and m of which is mu.

00:23.020 --> 00:28.960
So these instructions helps us work with data stored in memory.

00:28.960 --> 00:37.690
So when we use the data, when we use the LDA instruction with a memory location like B num, we are

00:37.690 --> 00:45.730
essentially loading the address of the memory location into a register called Rax and think of Rax as

00:45.730 --> 00:50.530
a temporary storage container that the computer's processor can use.

00:50.530 --> 00:59.530
So if we want to get the memory address of Rax, we can use l e a but if we want to, if we want the

00:59.530 --> 01:05.890
actual data value stored at the memory address, we can use MOV when we use MOV.

01:05.920 --> 01:15.100
If we put square braces here around binom, we get the data value itself and not the address.

01:15.100 --> 01:17.990
And as you can see here, I added comments here.

01:17.990 --> 01:24.230
When we use the square brackets with move and rax load the value stored at the memory address stored

01:24.350 --> 01:28.040
in binom into Rax and.

01:29.880 --> 01:30.630
So.

01:31.770 --> 01:35.250
Uh, let's actually in this context here.

01:35.490 --> 01:38.730
Racks Racks is 64 bit register.

01:38.730 --> 01:43.500
So this means it can hold eight bytes of data.

01:43.500 --> 01:48.690
So the data is stored in specific way called little endian.

01:48.690 --> 01:54.660
So where the rightmost byte smallest part of the value is stored in the lowest memory address.

01:54.660 --> 02:02.460
So in the case we are mainly interested in the smallest part of racks which is called a L.

02:02.490 --> 02:11.640
So this holds just one byte of data and that's the part we want to use when we need to store or manipulate

02:11.670 --> 02:12.870
small values.

02:12.870 --> 02:16.140
So sometimes we want to start with a clean slate.

02:16.140 --> 02:17.610
In register.

02:17.610 --> 02:28.950
To do this, we use XOR instruction to set a register to zero and in this case it is used like here

02:28.950 --> 02:32.560
XOR racks racks here.

02:33.490 --> 02:34.240
And.

02:38.960 --> 02:40.940
And after that we use the.

02:41.270 --> 02:48.830
We also use the restore the value of RSP from Rbp, which is clean up the stack frame.

02:50.190 --> 02:51.750
And to avoid.

02:52.730 --> 02:58.040
And also when we move the data between memory and registers, we need to be careful about the size of

02:58.040 --> 02:58.430
the data.

02:58.430 --> 03:02.660
For example, move P over here.

03:02.840 --> 03:04.160
Yeah, it's actually.

03:04.160 --> 03:04.600
Yes.

03:04.610 --> 03:05.420
Move.

03:06.410 --> 03:07.070
Beaver.

03:10.140 --> 03:10.680
Aw, yeah.

03:10.710 --> 03:13.980
Move by Rex Moves.

03:14.010 --> 03:18.150
Eight bytes from rags to the memory location.

03:18.180 --> 03:18.900
Beaver.

03:18.930 --> 03:21.030
So this might be more than we.

03:21.600 --> 03:22.680
More than you intend.

03:22.680 --> 03:27.570
And potentially overwriting other important data in memory.

03:27.570 --> 03:37.500
And to avoid overwriting unintended data, you can use move p r a l instead.

03:37.500 --> 03:45.540
So this moves just one byte value in a l to the memory location beaver leaving the rest of the data

03:45.720 --> 03:50.490
untouched and Indian ness on the value representation here.

03:50.490 --> 04:00.330
So when reading data from memory like for example text one the computer stores the data in little endian

04:00.480 --> 04:01.080
notation.

04:01.080 --> 04:06.420
So this means the smallest part of the value stored at the lowest memory address.

04:07.020 --> 04:11.950
And you can use l e a to load memory addresses.

04:11.950 --> 04:17.680
It makes your code more understandable since it's clear that you are dealing with addresses and it it

04:17.680 --> 04:19.900
can also be faster for some calculations.

04:19.900 --> 04:26.680
However, in this context, the l e a won't be used for calculations.

04:26.680 --> 04:29.200
So now what we're going to do is.

04:30.640 --> 04:32.800
And we will make this program.

04:32.800 --> 04:35.140
So there's an output for this program.

04:35.140 --> 04:38.790
We will use the debugger to step through each instructions.

04:39.310 --> 04:48.190
CSM is helpful here, but we define some variables of different sizes, including an array of five double

04:48.190 --> 04:51.370
words filled with zeros.

04:52.370 --> 04:53.150
As you can see here.

04:53.150 --> 04:58.190
So we also define some items in sections BS.

04:58.670 --> 05:05.510
Now look in your debugger for a span, the stack pointer, it's a very high value.

05:06.820 --> 05:07.570
And.

05:10.530 --> 05:16.080
And here the stack pointer refers to an address in high memory.

05:16.080 --> 05:24.780
So the stack in an area in memory used for temporarily storing data and the stack will grow as more

05:24.780 --> 05:34.170
data is stored in it and it will grow in the downward direction from higher addresses to lower addresses.

05:34.170 --> 05:41.970
So the stack pointer RSP here like this will decrease every time you put data on the stack.

05:41.970 --> 05:45.960
So we will discuss the stack in a separate section of our course.

05:45.960 --> 05:51.630
But remember already that the stack is placed somewhere in high memory.

05:52.380 --> 05:59.070
Now we will debug this program here by clicking on debug and as you can see, it's started.

05:59.070 --> 06:08.520
So if you can't see this right tab here, in order to see it here, you need to go to debug and click

06:08.520 --> 06:09.420
on Show Register.

06:09.420 --> 06:18.220
You can also use the control R to show this register tab on the right side of your screen now.

06:19.240 --> 06:20.590
That sit here.

06:20.590 --> 06:33.490
So here we use this l l a no l e a instruction, which means, as I explained here in this lecture load

06:33.490 --> 06:38.890
effective address to load the memory address of Benham here.

06:39.540 --> 06:42.630
To load the memory address of Bynum into Rex.

06:42.630 --> 06:49.650
We can obtain the same result with MV without the square braces around Bynum.

06:49.710 --> 06:56.790
So if we use square braces like this with mov instruction like we used here.

06:57.580 --> 06:58.150
Right.

06:58.990 --> 07:04.150
Uh, we are loading the value and not the address at Benham interacts.

07:04.150 --> 07:05.920
But we are not loading.

07:05.940 --> 07:07.000
Only Benham interacts.

07:07.000 --> 07:14.920
But because the Rax is 64 bit or eight byte register and more bytes are loaded into Rax and our Benham

07:14.920 --> 07:22.810
is the rightmost byte in Rax here, which is, as I explained here, this is little endian and here

07:22.810 --> 07:32.870
we are only interested in the register as so you when you require rax to contain only only the value

07:32.870 --> 07:39.010
of one, two, three, you will first have to clear rax like for example.

07:42.450 --> 07:43.110
Here.

07:44.550 --> 07:46.740
Like X or with x?

07:46.740 --> 07:47.760
With x or.

07:48.210 --> 07:52.670
Actually, we need to stop the program from debugging here and we will continue again.

07:52.680 --> 08:02.520
So as I said, like if you want to react to contain only value one, two, three, you need to.

08:03.970 --> 08:08.740
Uh, clear the racks with X or x or Rex.

08:09.420 --> 08:10.320
Rex.

08:10.430 --> 08:11.160
Rex.

08:11.170 --> 08:12.820
And that's it.

08:13.800 --> 08:16.710
And you can also use instead of.

08:17.770 --> 08:19.690
Like using the.

08:23.020 --> 08:31.000
Instead of using the move racks being on like this, you can use.

08:33.010 --> 08:34.630
L Aw, Yeah.

08:34.900 --> 08:37.960
Instead of using this, actually, instead of writing this.

08:37.990 --> 08:38.350
Yeah.

08:38.350 --> 08:41.710
You instead of using this, you can use move.

08:43.150 --> 08:44.020
Al.

08:46.470 --> 08:47.160
And.

08:48.710 --> 08:51.170
Be in braces.

08:52.270 --> 08:57.910
And be careful about the sizes of data you are moving to and from memory.

08:58.690 --> 09:03.100
Look, for instance, let's actually turn this.

09:05.980 --> 09:06.370
Here.

09:06.400 --> 09:10.450
Look, for instance in move beaver racks.

09:10.450 --> 09:17.080
With this instruction, we are moving the eight bytes in racks to the address bar.

09:17.110 --> 09:24.010
If you only intended to write one, two, three, two Beaver, you can check with your debugger that

09:24.010 --> 09:29.410
you overwrite another seven bytes in memory so you can choose it.

09:30.070 --> 09:37.660
Choose type D for beaver in the CSM memory window and this can introduce nasty bugs in your program.

09:37.660 --> 09:47.800
To avoid that, replace the instructions with move Beaver a l i as I explained here.

09:47.830 --> 09:48.640
So.

09:50.300 --> 09:53.740
Let's actually try this debug this here.

09:53.750 --> 10:00.890
And as you can see here we are seeing registers, hacks and infos on our register table.

10:02.080 --> 10:09.370
And now what we're going to do is we will use the sample command this as main and.

10:11.730 --> 10:14.310
As you can see, we are also seeing the symbol here.

10:14.700 --> 10:18.780
So now we will use the red elf at the command line.

10:18.810 --> 10:27.420
Remember that we asked NSM to assemble using the Elf command like with this debugging settings here.

10:27.540 --> 10:31.260
But let's actually let's go to terminal here.

10:32.520 --> 10:35.790
And compile this with make file here.

10:35.790 --> 10:39.890
And also we will generate the elf.

10:41.800 --> 10:43.510
Here on the list as well.

10:43.810 --> 10:47.800
So we will go to here We are in exabytes.

10:50.310 --> 10:51.750
Actually, we had a.

10:53.160 --> 10:54.180
Britain the.

10:55.390 --> 10:58.480
Make file in another project so we can copy it.

10:59.050 --> 10:59.530
Just.

11:00.920 --> 11:01.350
Parsley.

11:02.170 --> 11:08.990
So we will just change the kicking to exabyte exabytes.

11:10.400 --> 11:12.080
Will be easy here.

11:14.350 --> 11:17.260
Search and replace.

11:18.050 --> 11:19.670
Kicking to.

11:21.220 --> 11:23.280
Bytes and replace.

11:23.290 --> 11:24.430
Now save it.

11:26.360 --> 11:27.290
Don't save.

11:27.290 --> 11:30.260
Now open the terminal here.

11:30.290 --> 11:31.160
Make.

11:31.190 --> 11:32.690
Make here.

11:32.690 --> 11:34.730
And as you can see here, our program is created.

11:34.760 --> 11:41.150
Now, if we run this, we will not get an output, but we will not get any error here because our programs

11:41.150 --> 11:42.710
works like a butter.

11:42.920 --> 11:49.550
And what we're going to do is we will use red elf.

11:49.670 --> 11:55.310
Red elf file header and memory.

11:57.020 --> 11:59.150
Now, not memory exabytes here.

11:59.420 --> 12:00.590
Exabytes.

12:01.040 --> 12:02.820
And that's it here.

12:02.840 --> 12:08.660
And you will get some general information about your executable memory here.

12:09.300 --> 12:10.970
The executable exabytes here.

12:10.970 --> 12:14.810
And look at the entry point address here.

12:14.960 --> 12:17.540
40 1020.

12:17.570 --> 12:21.350
That is the memory location of the start of our program.

12:21.350 --> 12:30.260
So between the program entry and the start of the code, as shown, um, as we will see on the GDB.

12:34.570 --> 12:36.100
Port, 1190.

12:37.640 --> 12:41.630
There is some overhead right here.

12:41.630 --> 12:46.370
We had 40, 11, 90 and 40.

12:46.460 --> 12:49.640
Ten, 20 and.

12:52.560 --> 12:56.820
That's actually also use the this as a main.

12:57.090 --> 12:57.510
Yeah.

12:57.510 --> 12:59.280
This is here gdb.

13:01.250 --> 13:01.900
LZ.

13:02.030 --> 13:02.380
Yeah.

13:03.000 --> 13:04.580
Uh, GDP.

13:05.040 --> 13:06.170
Exabytes.

13:10.230 --> 13:11.880
This as main.

13:15.290 --> 13:17.960
And here for 1110.

13:20.700 --> 13:22.350
Is it true for us?

13:26.210 --> 13:27.410
Um, let's actually.

13:54.730 --> 14:02.650
Now here, our starting point of our program is 4011.

14:03.570 --> 14:04.750
Ten, right?

14:07.520 --> 14:08.330
And.

14:08.980 --> 14:10.900
We're going to try this with Rudolph.

14:11.890 --> 14:21.490
Our entry entry point is 40 1020, and there's some overhead in our program, and the heater provides

14:21.490 --> 14:28.810
us with additional information about the operating system and the executable code as well here, operating

14:28.810 --> 14:29.650
system.

14:29.800 --> 14:33.370
And we have the size of the section headers and so on.

14:33.880 --> 14:42.670
And Rudolph is convenient for exploring a binary executable as well, which you can use the symbols

14:42.670 --> 14:46.540
parameter and we will grab the main from it.

14:46.540 --> 14:49.990
So red elf symbols.

14:51.780 --> 14:56.340
Exabytes and we will use pip here.

14:56.370 --> 14:57.270
Grep.

14:58.290 --> 14:58.890
Main.

15:01.380 --> 15:03.600
And there we have it.

15:06.620 --> 15:07.820
For the symbols mean.

15:07.820 --> 15:15.150
So with grep we specify that we are looking for all lines with the word main in it.

15:15.170 --> 15:20.060
So here you can see the main function starts at 40 1110.

15:21.220 --> 15:21.670
Um.

15:21.670 --> 15:22.570
And.

15:24.300 --> 15:26.490
As we saw in GDB.

15:28.620 --> 15:28.950
Port.

15:28.950 --> 15:30.060
1110.

15:30.240 --> 15:30.810
Right.

15:32.450 --> 15:35.330
And in this example.

15:37.800 --> 15:44.220
We need to look in the symbols table for every occurrence of the label start.

15:44.220 --> 15:52.350
So we see start of section data and BSS.

15:53.120 --> 15:55.010
Which is and the start of the program.

15:55.010 --> 16:04.340
We can also see the start of the program as well with our red symbols, but with grep command in order

16:04.340 --> 16:10.040
to see that, we will use the start and.

16:12.870 --> 16:14.040
Yeah, that's it here.

16:14.040 --> 16:19.110
As you can see here, we have start data, start here.

16:19.230 --> 16:20.760
These are the start point.

16:20.790 --> 16:23.970
Let's actually compare them with our.

16:27.000 --> 16:27.750
1020.

16:27.780 --> 16:30.180
We are still not on the entry point.

16:31.280 --> 16:31.820
Yes.

16:31.820 --> 16:36.110
Here and start our entry point actually corresponds here.

16:36.170 --> 16:42.800
Now we need to also see what we have in memory with the instruction here.

16:44.020 --> 16:46.120
Now in order to again.

16:47.890 --> 16:57.850
We will use the tail plus ten and we will use sort minus key to are here.

16:59.230 --> 17:05.860
And this instruction ignores some lines that are not interesting to us right now.

17:05.860 --> 17:10.960
So we sort on the second column, the memory address in reverse order.

17:10.960 --> 17:20.740
As you can see, some basic knowledge of Linux commands comes handy and the start of the program is

17:20.740 --> 17:25.600
at some low address and the start of the main.

17:26.390 --> 17:27.420
Is that?

17:29.080 --> 17:31.150
Part of the main is.

17:36.530 --> 17:38.180
Sexually see it here?

17:39.710 --> 17:40.490
We actually.

17:42.030 --> 17:43.530
So it improves here.

17:43.530 --> 17:44.030
Yeah.

17:44.070 --> 17:46.800
Start with the main is 4011.

17:46.800 --> 17:47.550
Ten.

17:48.090 --> 17:48.720
Right.

17:50.590 --> 18:02.590
And look look for the start of the section data here in this for ten, 20, 40 in data starts with for

18:02.590 --> 18:09.190
1020 with the address of all this variable and the start section of B s.

18:09.700 --> 18:13.270
We also saw that here.

18:13.960 --> 18:14.980
Note here.

18:16.290 --> 18:23.880
Start 40, 40, 39, and with the address reserved for its variables as well.

18:23.880 --> 18:27.060
So now let's summarize our findings here.

18:27.060 --> 18:37.380
So we found we found at the beginning of this lecture that the stack is in high memory, which we saw

18:37.380 --> 18:39.960
this with RSP here.

18:40.590 --> 18:41.760
RSP here.

18:43.040 --> 18:51.950
And with Rudolph, we found that the executable code is at the lower side of memory and on top of the

18:51.950 --> 18:54.740
executable code we have section data.

18:54.740 --> 19:01.750
And on top of that, on on top of the section data, we have section B, s.

19:01.800 --> 19:03.380
S here.

19:06.160 --> 19:12.610
But in this here, we as you know, we are using the reverse order here.

19:12.820 --> 19:14.080
And.

19:16.050 --> 19:27.150
And this high memory can grow and it grows in the downward direction toward Section BS and the available

19:27.150 --> 19:38.880
free memory between the stack and the other section is called Heap H, a heap, and the memory in the

19:38.880 --> 19:41.910
section that is assigned at runtime.

19:41.910 --> 19:43.950
So you can easily check that.

19:44.820 --> 19:46.320
And now.

19:48.270 --> 19:50.760
Well, let's actually go here.

19:50.760 --> 19:57.150
And in this case, as you can see here, we have QR risk reserved variables here.

19:57.150 --> 19:59.400
And we.

20:00.700 --> 20:02.260
Let's actually change this to.

20:03.600 --> 20:06.480
Uh, 33 of oops.

20:06.480 --> 20:07.220
Not this for.

20:09.760 --> 20:14.290
Let's change 3 to 3000 and you will.

20:14.290 --> 20:15.970
Actually, we need to stop this for.

20:15.970 --> 20:17.560
Sorry for here.

20:18.960 --> 20:25.860
So if we change 3 to 3000 and save the program, make again.

20:26.280 --> 20:31.340
And, uh, sorry, we had some error here.

20:31.350 --> 20:33.150
I think we messed with the code here.

20:33.150 --> 20:33.810
Yes.

20:36.470 --> 20:43.550
And why we have zero here, we will change 3 to 3000.

20:44.400 --> 20:45.900
And we will make again.

20:45.900 --> 20:48.630
And as you can see, it's compiled now.

20:49.610 --> 20:54.240
Now we rebuild the program with make.

20:54.250 --> 20:58.110
And now let's look the size again here LA.

20:59.070 --> 21:00.630
And as you can see, it's.

21:02.140 --> 21:02.680
Here.

21:05.800 --> 21:11.560
And we will use the try this with Rudolph again the same command.

21:19.060 --> 21:26.980
And as you can see here, the size here is significantly, significantly changed.
