WEBVTT

1
00:00.740 --> 00:02.240
Hello and welcome back.

2
00:02.570 --> 00:09.080
In this lesson we are going to learn x64 calling convention, also known as Microsoft Calling Convention.

3
00:10.070 --> 00:12.320
So let's take a look at what it means.

4
00:12.770 --> 00:19.010
Calling convention is a set of rules which determine how parameters are passed to functions, and how

5
00:19.010 --> 00:19.460
they return.

6
00:19.460 --> 00:21.050
Values are also handled.

7
00:22.010 --> 00:22.310
Stack.

8
00:22.310 --> 00:22.940
Example.

9
00:22.940 --> 00:27.470
We have a function with four arguments: arg1, arg2, arg3, arg4.

10
00:28.400 --> 00:33.890
According to Microsoft calling convention, you need to pass the first argument to -.

11
00:34.460 --> 00:40.700
We're going to move the second argument to -, the third one to -, and the fourth one to -.

12
00:41.240 --> 00:44.450
Then you have to allocate shadow space of 32 bytes.

13
00:44.450 --> 00:45.980
Then you call the function.

14
00:46.070 --> 00:49.250
So when the function runs, it will make use of all these arguments.

15
00:49.760 --> 00:52.310
Now what if you have more than four arguments?

16
00:52.430 --> 00:57.620
If you have more than four arguments, assuming we have eight arguments, then the remaining arguments

17
00:57.620 --> 01:01.610
five, six, seven, and eight need to be pushed to the stack like this.

18
01:02.360 --> 01:06.920
And then this will require a recalculation of the shadow space.

19
01:08.240 --> 01:13.430
So normally in x64 environment we don't push arguments to the stack.

20
01:13.430 --> 01:18.140
Instead, we move arguments directly into the stack using move statement.

21
01:18.860 --> 01:25.400
So this will be the most common way to pass parameters using the stack.

22
01:25.820 --> 01:30.740
So as usual, you notice here the first four is to move to the -.

23
01:31.160 --> 01:38.060
- - - and -, but this time, instead of pushing to the stack, we will allocate space on the stack

24
01:38.600 --> 01:42.770
for these four arguments which we are going to push to the stack.

25
01:43.520 --> 01:45.560
So this argument six.

26
01:45.920 --> 01:54.020
Argument five, sorry. Argument five will be moved to - plus 32. Argument six will be moved to - plus

27
01:54.020 --> 01:54.650
40.

28
01:55.130 --> 02:01.130
Argument seven will move to - 48, and argument eight will move to - plus 56.

29
02:01.130 --> 02:06.920
Then only you call the function, but in this case you need to recalculate how much shadow space.

30
02:07.100 --> 02:15.710
So the shadow space will be shadow space 32 plus four arguments times eight, because each of the arguments

31
02:15.710 --> 02:17.150
takes up a quadword.

32
02:17.240 --> 02:22.430
So we have four arguments will be 32, 32 plus 32 gives you 64.

33
02:22.430 --> 02:30.950
So you need to allocate space in the stack for 64 arguments, for the shadow space and four for the

34
02:30.950 --> 02:32.360
argument 5, 6, 7, 8.

35
02:32.870 --> 02:37.310
If you only have five arguments, then you take one times eight.

36
02:37.310 --> 02:39.140
That will give you 40.

37
02:39.530 --> 02:42.320
That means sub - 40.

38
02:42.620 --> 02:46.550
If you have six arguments, then it will be 32 plus 16.

39
02:46.730 --> 02:48.620
Two times eight is 16.

40
02:48.620 --> 02:51.140
So 32 plus 16 is 48.

41
02:51.140 --> 02:52.940
That means it will be sub - 48.

42
02:52.940 --> 02:53.480
And so on.

43
02:53.480 --> 02:58.130
So this is how you calculate how much of the shadow space you need to allocate

44
02:58.310 --> 03:02.900
when you have more than four parameters that you pass to the function.

45
03:04.370 --> 03:07.100
So a diagram will make this easier to understand.

46
03:07.130 --> 03:10.640
Now assuming that this is a stack here and this is a register.

47
03:10.880 --> 03:18.320
So before the call is made, you will load your registers - with the first argument, - second argument,

48
03:18.620 --> 03:21.560
- with the third argument, - with the fourth argument.

49
03:22.100 --> 03:31.280
Thereafter, you will then allocate shadow space, and then you will also allocate four quad words

50
03:31.580 --> 03:33.620
for the arguments.

51
03:33.620 --> 03:37.880
So four times eight, 32 plus 32 here is 64.

52
03:38.420 --> 03:40.760
So at the moment your - is pointing here.

53
03:40.760 --> 03:47.990
The stack pointer - points to the bottom of the stack, and - points to the top of the stack.

54
03:49.250 --> 03:49.580
Okay.

55
03:49.580 --> 03:53.000
So now how do you pass arguments to the stack?

56
03:53.930 --> 03:56.660
How do you now move the arguments to the stack?

57
03:57.050 --> 04:04.280
You use the offset - plus 32 to access the fifth argument, - plus 40 to access the sixth argument,

58
04:04.730 --> 04:08.090
- plus 48 for the seventh argument, and - 56 for eighth

59
04:08.090 --> 04:08.630
argument.

60
04:08.630 --> 04:09.740
Why 32?

61
04:09.770 --> 04:13.340
Because the return, because the shadow space is of 32.

62
04:13.430 --> 04:18.200
Since your - is at the top of the stack, so it must plus 32 to get to the fifth argument.

63
04:18.230 --> 04:24.200
That is the reason why you plus 32 here to access the fifth argument.

64
04:24.200 --> 04:27.590
So you will save a few arguments there directly instead of pushing.

65
04:27.800 --> 04:32.240
Instead of pushing like this in reverse order, you move it directly inside.

66
04:32.420 --> 04:36.500
Same thing with the sixth argument, sixth argument - plus 40, and so on.

67
04:37.070 --> 04:41.120
So after the call is made, the return address will be pushed to the stack like this.

68
04:41.600 --> 04:43.670
So return address is pushed to the stack.

69
04:44.060 --> 04:48.740
And then after that, you will do a push - inside your new function.

70
04:48.740 --> 04:55.970
And that will push the old address of the - into the stack itself, so that you can keep track

71
04:55.970 --> 04:59.630
of where was the old stack frame.

72
05:00.170 --> 05:04.970
So now the old - is here, so - will move to the top.

73
05:04.970 --> 05:06.890
Then you will move - to -.

74
05:06.890 --> 05:09.380
That will effectively move - right to the top

75
05:09.820 --> 05:12.640
to point to the same location as the -.

76
05:13.210 --> 05:19.720
So now - is pointing here, and this will always be remaining here throughout the execution of the

77
05:19.750 --> 05:20.620
function.

78
05:20.620 --> 05:22.420
But - is free to move around.

79
05:22.570 --> 05:29.710
So we will use - as a base pointer to refer to any variables or arguments.

80
05:30.280 --> 05:37.930
So in this case here, if you wanted to refer to the fifth argument inside the function, you will do

81
05:37.960 --> 05:39.280
- plus 48.

82
05:39.910 --> 05:40.360
Why?

83
05:40.390 --> 05:42.340
Because from here to here is eight.

84
05:42.340 --> 05:43.840
Here to here is 32.

85
05:43.870 --> 05:44.710
So 40.

86
05:45.280 --> 05:46.540
And then here to here another eight.

87
05:46.540 --> 05:47.440
So 48.

88
05:47.980 --> 05:51.430
If you want to access the sixth argument, then you would do

89
05:51.910 --> 05:59.620
plus another eight, becomes - plus 56. If you want to access the seventh argument, is - plus 64, and

90
05:59.620 --> 06:00.160
so on.

91
06:00.880 --> 06:04.870
So then let's say after this you want to create local variables.

92
06:04.870 --> 06:06.370
You can do so like this.

93
06:07.060 --> 06:10.210
Let's say you want to create five local variables.

94
06:10.210 --> 06:11.290
You will just move.

95
06:11.620 --> 06:13.960
You do sub - 40.

96
06:13.960 --> 06:14.590
Why 40?

97
06:14.590 --> 06:16.870
Because five times eight is 40.

98
06:17.680 --> 06:20.770
Each variable will be eight bytes or quadword.

99
06:21.550 --> 06:23.620
So what you have here will be

100
06:23.950 --> 06:29.860
1, 2, 3, 1, 2, 3, 4, 5.

101
06:29.860 --> 06:31.480
So five times 8, 40.

102
06:31.510 --> 06:32.410
That's how you do it.

103
06:32.680 --> 06:39.850
And if you wanted to access these local variables, you would take the - minus eight to access the

104
06:39.850 --> 06:41.350
first local variable.

105
06:41.590 --> 06:45.970
Then to access the second local variable will be - minus 16, and so on.

106
06:46.240 --> 06:50.800
So you notice that the - is very useful.

107
06:50.800 --> 06:55.000
It is a base pointer for your stack, for your new stack frame.

108
06:55.240 --> 06:56.710
So this is called a stack frame.

109
06:56.710 --> 06:58.450
By the way, this is the old stack frame.

110
06:58.450 --> 06:59.410
This is the new one.

111
06:59.410 --> 07:06.250
So - will then be used to access all the arguments by taking the offset plus.

112
07:06.670 --> 07:10.300
And to access the local variables, you take the offset minus like this.

113
07:11.470 --> 07:11.740
All right.

114
07:11.740 --> 07:16.360
So in the next lesson we will do some practicals so that all this will become clear to you.

115
07:16.390 --> 07:17.680
That's all for this video.

116
07:17.680 --> 07:18.820
Thank you for watching.