WEBVTT

00:01.350 --> 00:03.029
Hello, this is Dr. Miller, and this

00:03.030 --> 00:04.559
is Episode two point one of

00:04.560 --> 00:05.560
Assembly.

00:07.970 --> 00:09.079
Today, we're going to learn about

00:09.080 --> 00:10.760
assembly language and suddenly an

00:11.000 --> 00:13.369
assembly instructions, identifiers,

00:13.370 --> 00:15.289
directives, and then creating

00:15.290 --> 00:16.699
a listing of a file

00:17.990 --> 00:19.120
assembly language.

00:20.600 --> 00:22.670
So machine language is the low level

00:22.880 --> 00:24.829
that a machine uses

00:24.830 --> 00:27.410
in order to execute instructions.

00:27.860 --> 00:29.539
And so, for example, if we would

00:29.540 --> 00:30.569
like to add Etext SBX

00:32.060 --> 00:34.099
and then store the result in X,

00:34.700 --> 00:35.876
we would run the machine

00:36.680 --> 00:37.905
instructions zero three C

00:38.630 --> 00:39.630
three.

00:39.800 --> 00:41.172
Now, clearly that's not very

00:41.450 --> 00:43.279
readable and it changes with

00:43.280 --> 00:44.539
different processor types

00:45.140 --> 00:46.316
and so a better language

00:47.480 --> 00:49.039
is needed and that language is

00:49.040 --> 00:50.040
assembly.

00:50.420 --> 00:52.279
So given the machine language

00:52.280 --> 00:53.946
zero three C three, in order to do

00:54.200 --> 00:55.880
the movement of data,

00:56.300 --> 00:57.917
we have the assembly language add

00:58.430 --> 00:59.869
yet SBX.

00:59.950 --> 01:01.609
So this will add those two registers

01:01.610 --> 01:03.439
together and then store the

01:03.440 --> 01:05.019
result in X.

01:06.080 --> 01:07.697
Now clearly this is more readable

01:07.790 --> 01:09.859
and it is a higher level language

01:09.860 --> 01:11.085
than writing something in

01:11.810 --> 01:13.370
binary in hex

01:13.820 --> 01:15.229
from a previous lecture, you should

01:15.230 --> 01:16.994
recognize that this is Hex given the

01:17.090 --> 01:19.159
zero X and the letter C

01:19.160 --> 01:20.160
in there.

01:21.200 --> 01:22.579
And then we have four different

01:22.580 --> 01:23.580
architectures.

01:23.720 --> 01:25.579
We can keep the same code and

01:25.580 --> 01:27.520
end up getting the right result.

01:28.550 --> 01:30.319
Additionally, optimizations can be

01:30.320 --> 01:31.699
made. So if you have a code that is

01:31.700 --> 01:33.317
not working or is not needed, the

01:33.830 --> 01:35.660
assembler and or compiler

01:36.080 --> 01:38.060
can get rid of those or

01:38.330 --> 01:40.039
pick a different instruction at the

01:40.040 --> 01:41.749
low level, that will be faster.

01:43.210 --> 01:44.589
And then the format of an assembly

01:44.590 --> 01:46.569
instructions is we have a pneumonic

01:46.570 --> 01:48.129
or something that you can remember,

01:48.130 --> 01:49.749
and then that is followed by

01:49.750 --> 01:50.750
operands.

01:52.510 --> 01:53.859
Now, there is a difference between

01:53.860 --> 01:55.439
an assembly line and a compiler.

01:55.450 --> 01:57.580
So with an assembler, generally,

01:57.880 --> 01:59.439
there's a one to one ratio of

01:59.440 --> 02:01.629
assembly instructions

02:01.630 --> 02:02.739
to machine code

02:03.490 --> 02:05.409
and an assembly is machine

02:05.410 --> 02:07.076
dependent. So if I write something

02:07.150 --> 02:09.219
in assembler four x eighty six,

02:09.220 --> 02:10.329
I have to write a completely

02:10.330 --> 02:11.555
different code for ARM or

02:12.340 --> 02:14.169
Fassbach, whereas

02:14.170 --> 02:15.729
if we have a compiler again, it's

02:15.730 --> 02:17.559
one higher level abstraction

02:18.130 --> 02:20.199
and so one high level line

02:20.200 --> 02:22.389
to create a variable

02:22.390 --> 02:24.007
or move. Some data might generate

02:24.460 --> 02:25.685
many machine and assembly

02:26.680 --> 02:28.629
instructions, but

02:28.630 --> 02:30.369
the benefit of it being higher level

02:30.370 --> 02:31.629
is that it's more portable.

02:31.630 --> 02:33.279
So you can write something and see

02:33.640 --> 02:35.306
and if you have a compiler, it can

02:35.410 --> 02:36.978
compiler to X eighty six code or

02:37.330 --> 02:38.889
a compiler to arm code

02:39.190 --> 02:40.758
and you don't have to change the

02:41.070 --> 02:42.250
the high level code.

02:42.760 --> 02:44.349
Now this is not always the case, but

02:44.350 --> 02:45.759
generally it is the case.

02:48.010 --> 02:49.509
So the assembler we're using for

02:49.510 --> 02:50.686
this class is Nazim, and

02:51.430 --> 02:52.430
so with that, we are

02:53.350 --> 02:55.114
actually underneath it using the new

02:55.330 --> 02:57.080
compiler collection.

02:57.100 --> 02:58.539
So this is a compiler that will

02:58.540 --> 02:59.540
compile code.

03:00.280 --> 03:01.599
And then we're also using the C

03:01.600 --> 03:03.339
programing language to interface

03:03.340 --> 03:04.680
with GCC.

03:05.950 --> 03:07.539
And then we should also be using

03:07.540 --> 03:09.729
make, so that's part of our template

03:09.730 --> 03:11.469
uses make in order to build

03:11.860 --> 03:12.860
the program.

03:14.170 --> 03:15.580
Assembly instructions.

03:16.830 --> 03:18.496
So, again, we have a pneumonic and

03:18.780 --> 03:20.549
then that is followed by operand, so

03:20.550 --> 03:22.118
the mnemonic is add, whereas the

03:22.410 --> 03:23.929
operands are what it's going to

03:24.240 --> 03:25.770
do, that operation on.

03:26.340 --> 03:27.960
And we have three general types.

03:27.970 --> 03:29.819
So we have registers, as

03:29.820 --> 03:31.919
we saw yak's SBX

03:32.040 --> 03:33.040
are registers memory

03:33.990 --> 03:36.180
locations, which we'll look at later

03:36.750 --> 03:38.250
and intermediate value.

03:38.290 --> 03:39.689
So that's an actual value that's

03:39.690 --> 03:41.639
hard coded inside of the binary.

03:43.110 --> 03:44.909
Additionally, we do have implied

03:45.180 --> 03:46.601
so, for example, an increment

03:47.370 --> 03:48.448
will affect a register

03:49.920 --> 03:51.292
by default, so it'll add one

03:51.840 --> 03:52.840
to that register or

03:53.850 --> 03:55.919
decrement will decrease the register

03:55.920 --> 03:56.920
by one.

03:58.370 --> 04:00.229
So example instructions, so we

04:00.230 --> 04:01.999
have our mnemonic, which is move,

04:02.510 --> 04:04.610
and then we have the Register SBX

04:04.910 --> 04:06.949
and we also have the the

04:06.950 --> 04:08.360
hard coded values seven.

04:08.720 --> 04:10.435
Right. So the seven is an immediate

04:10.520 --> 04:12.409
and then SBX is

04:12.410 --> 04:13.410
a register.

04:14.220 --> 04:16.249
Here we have to register so into

04:16.570 --> 04:18.749
Ebix, so this says that

04:19.110 --> 04:21.179
SBX is value is going to go

04:21.180 --> 04:23.430
get copied into X

04:23.940 --> 04:26.130
or increment X or decrement

04:26.150 --> 04:28.319
X, so those again, would increment

04:28.320 --> 04:30.480
or decrement that register.

04:32.520 --> 04:34.679
And the way that instructions are in

04:34.680 --> 04:36.930
Nazem is that we have an optional

04:36.960 --> 04:37.979
right, so the brackets mean

04:37.980 --> 04:39.389
optional. We have a label

04:40.080 --> 04:41.746
followed by a mnemonic, so we have

04:42.060 --> 04:43.060
to have a mnemonic.

04:43.350 --> 04:45.065
And then if a mnemonic doesn't have

04:45.270 --> 04:46.829
implied operands, we need some

04:46.830 --> 04:48.202
operands and then we have an

04:48.720 --> 04:50.160
optional comment.

04:50.560 --> 04:51.689
And so here are some example.

04:51.690 --> 04:53.310
Mnemonics, move, add,

04:53.790 --> 04:56.009
sub moule, jump,

04:56.010 --> 04:57.010
call.

04:57.300 --> 04:58.589
Notice that they aren't necessarily

04:58.590 --> 05:00.059
spelled right. So there's no eone

05:00.060 --> 05:01.060
move.

05:01.530 --> 05:02.820
Jump doesn't have a you,

05:04.050 --> 05:06.269
but those are examples of mnemonics

05:06.270 --> 05:07.649
and then all of the Marnix that will

05:07.650 --> 05:09.620
learn and then comments.

05:09.630 --> 05:11.480
So a comment starts with

05:11.490 --> 05:12.299
a semicolon.

05:12.300 --> 05:13.679
So if you're used to programing and

05:13.680 --> 05:14.680
C you might just

05:15.540 --> 05:17.039
put a semicolon at the end of your

05:17.040 --> 05:19.170
statements, but that is a

05:19.200 --> 05:20.200
Nazeem comment.

05:23.690 --> 05:25.939
Directives, so directives

05:25.940 --> 05:27.409
are not actual instructions, they

05:27.410 --> 05:28.978
just tell the assembler that you

05:29.270 --> 05:31.129
want to do something, you want

05:31.130 --> 05:33.259
it to, for example, set the size

05:33.260 --> 05:35.419
of the stack, define some memory,

05:35.420 --> 05:36.800
define some constants.

05:37.430 --> 05:38.998
So directives are are for humans

05:39.740 --> 05:41.839
to make things easier, but

05:41.870 --> 05:43.193
they aren't actual assembly

05:43.790 --> 05:44.790
instructions.

05:45.940 --> 05:47.829
So, for example, percent define.

05:48.370 --> 05:49.929
So if you've programed in a language

05:49.930 --> 05:51.351
like C Pound define allows us

05:51.850 --> 05:53.050
to create constants.

05:53.410 --> 05:55.389
So also percent define

05:55.390 --> 05:56.390
does so says percent

05:57.430 --> 05:58.649
define size 10.

05:58.660 --> 06:00.375
So every place that we'll see size,

06:00.730 --> 06:02.445
it just replaces it with the actual

06:02.500 --> 06:03.500
value of ten.

06:04.570 --> 06:05.942
So this instruction would be

06:06.490 --> 06:08.350
the same as movie 10.

06:11.400 --> 06:13.017
We have data directives, which we

06:13.050 --> 06:14.690
will have to do a lot of,

06:15.150 --> 06:16.277
and so the D stands for

06:17.010 --> 06:18.629
defined. So we've got to find a

06:18.630 --> 06:20.549
bite, define a word

06:20.550 --> 06:21.730
and define a D word.

06:21.750 --> 06:23.514
I remember a bite is one bite, which

06:23.550 --> 06:24.550
is Apitz.

06:24.690 --> 06:25.690
A word is two bites

06:26.850 --> 06:27.959
or 16 bits.

06:27.960 --> 06:29.790
And a double word

06:30.150 --> 06:31.859
is thirty two bites.

06:34.460 --> 06:35.510
Identifiers,

06:36.860 --> 06:38.428
so throughout the course, you're

06:38.750 --> 06:40.489
going to be creating different

06:40.490 --> 06:42.470
variables or identifiers,

06:42.860 --> 06:44.281
and so we need to know how to

06:44.720 --> 06:46.309
define them and what are actually

06:46.310 --> 06:47.239
allowed.

06:47.240 --> 06:48.661
So we use them for variables,

06:48.800 --> 06:49.829
constants, procedures

06:50.660 --> 06:52.519
or functions and

06:52.520 --> 06:53.520
labels.

06:54.410 --> 06:56.149
And so the main

06:56.300 --> 06:58.129
key here is that you

06:58.130 --> 06:59.269
need to start your variables

06:59.270 --> 07:00.739
basically with a letter.

07:01.010 --> 07:03.289
So that's the the easiest way

07:03.980 --> 07:05.449
to start it. And then you can add

07:05.450 --> 07:07.009
some of these additional characters.

07:07.010 --> 07:08.959
But generally, most of my variables

07:09.410 --> 07:11.027
would just have letters, possibly

07:11.720 --> 07:13.092
numbers within them and then

07:13.610 --> 07:15.276
maybe underscore is to make things

07:15.470 --> 07:16.470
more readable.

07:19.100 --> 07:20.864
All right, so here are some examples

07:21.110 --> 07:23.149
of addition and subtraction, so move

07:23.150 --> 07:25.429
into X 100 in hex,

07:26.000 --> 07:27.949
add four hundred X,

07:27.950 --> 07:29.869
so one plus four should give us

07:29.870 --> 07:32.239
five and then subtract

07:32.240 --> 07:33.799
X two hundred X.

07:34.310 --> 07:35.719
So that should give us three hundred

07:35.720 --> 07:36.720
and hex.

07:37.250 --> 07:39.529
So if you open up your

07:39.530 --> 07:40.951
editor you can type this code

07:41.420 --> 07:43.399
in and see what the result is.

07:44.210 --> 07:45.631
The dump regs one, we'll just

07:46.100 --> 07:48.079
print off what all the registers are

07:48.860 --> 07:50.119
and then it puts a number one in

07:50.120 --> 07:52.220
front of it. So it does

07:53.390 --> 07:54.829
hash tag number one.

07:54.980 --> 07:56.719
And so you can call numbers multiple

07:56.720 --> 07:58.100
times and you'll see

07:59.090 --> 07:59.929
each one of those.

07:59.930 --> 08:01.547
You can put a different number in

08:01.550 --> 08:02.479
there.

08:02.480 --> 08:04.195
So if you have the template already

08:04.220 --> 08:05.809
set up, I would go ahead and pause

08:05.810 --> 08:07.378
the video and I would enter this

08:07.850 --> 08:10.040
in and see what it produces and

08:10.280 --> 08:11.929
maybe change the numbers in here and

08:11.930 --> 08:13.459
see if you get a different result,

08:16.130 --> 08:17.360
generating a listing.

08:18.650 --> 08:20.449
So listing will give us information

08:20.450 --> 08:21.450
about offsets and

08:22.430 --> 08:24.049
binary code for commands,

08:24.440 --> 08:26.204
and it also will help us when we are

08:26.240 --> 08:27.550
trying to find errors.

08:28.160 --> 08:29.160
So this is to tell

08:30.110 --> 08:31.459
us that we are using the program.

08:31.460 --> 08:33.028
Nazeem, we are using LTH because

08:33.559 --> 08:34.784
I'm on Lennix, I'm naming

08:35.570 --> 08:37.489
the listing and then this

08:37.490 --> 08:39.499
is the example that I want

08:39.500 --> 08:40.500
to do for it.

08:41.090 --> 08:42.805
So I'm going to go ahead and switch

08:42.860 --> 08:44.209
to a

08:44.780 --> 08:46.495
terminal window and go ahead and do

08:46.610 --> 08:47.610
that.

08:54.590 --> 08:56.149
So I'm going to create my project

08:56.150 --> 08:57.150
here.

08:59.290 --> 09:01.029
I'll just call it two point one.

09:02.290 --> 09:04.054
So now if I look inside my directory

09:04.330 --> 09:06.159
of my projects, so I already

09:06.160 --> 09:07.728
entered that before I started, I

09:08.080 --> 09:09.279
have a directory called two point

09:09.280 --> 09:10.280
one.

09:12.680 --> 09:14.149
And now I should have my assembly

09:14.150 --> 09:15.770
file, so I'll go ahead and edit it.

09:18.190 --> 09:19.570
And so let's put some

09:20.140 --> 09:21.140
code in here.

09:26.400 --> 09:28.019
So I'm just going to move the value

09:28.020 --> 09:30.029
of negative 10 into yak's,

09:30.030 --> 09:31.080
maybe I do another one.

09:41.520 --> 09:43.889
I'll go ahead and write and quit,

09:44.760 --> 09:46.524
I can run make in order to make sure

09:46.800 --> 09:47.800
that my program will

09:48.660 --> 09:50.069
assemble and compile

09:50.670 --> 09:52.379
so you can see right make is the

09:52.380 --> 09:53.790
program that we've been using.

09:54.150 --> 09:56.279
It's running the command, Nazeem,

09:56.280 --> 09:58.169
and it's also running in order

09:58.170 --> 09:59.459
to generate our output.

09:59.910 --> 10:01.739
And then the driver see is

10:01.740 --> 10:03.390
the the program that

10:03.840 --> 10:05.219
provides the skeleton so that our

10:05.220 --> 10:06.220
program can run.

10:07.290 --> 10:08.669
And so if we want to generate a

10:08.670 --> 10:09.670
listing.

10:16.980 --> 10:19.370
All right, so Nazem minus F.L.

10:19.380 --> 10:21.420
So that's the type of executable

10:22.770 --> 10:24.338
minus L is the listing file that

10:24.630 --> 10:26.069
we're going to generate and then two

10:26.070 --> 10:27.929
point one to ASM is a file that I

10:27.930 --> 10:29.009
want to use for that.

10:31.140 --> 10:32.729
So now I can look at that, I can use

10:32.730 --> 10:34.289
a program like Cat,

10:34.710 --> 10:36.539
which means concatenate or print to

10:36.540 --> 10:37.540
the terminal.

10:41.710 --> 10:43.419
So we can see and hear that,

10:43.840 --> 10:46.059
ah, this is our assumption

10:46.060 --> 10:47.079
and we can see the different

10:47.080 --> 10:49.299
instructions, so.

10:50.310 --> 10:52.289
The instruction to move something

10:52.290 --> 10:53.629
into X

10:54.150 --> 10:55.740
is this B eight

10:56.490 --> 10:57.719
and then we can see we've got a

10:57.720 --> 10:59.590
bunch of F's and a six.

11:00.390 --> 11:01.909
So again, remember that this is

11:02.640 --> 11:04.409
stored in twos complement, which we

11:04.410 --> 11:06.020
talked about in a previous lecture.

11:06.570 --> 11:08.187
So and it also stores it a little

11:08.250 --> 11:09.119
bit backwards.

11:09.120 --> 11:10.120
Right. So the first

11:11.010 --> 11:12.629
byte is right here.

11:13.320 --> 11:14.669
The second byte is right here.

11:14.670 --> 11:15.989
The third byte is right here in the

11:15.990 --> 11:17.070
fourth byte is right here.

11:17.730 --> 11:19.004
And we'll talk about in in

11:19.350 --> 11:21.059
subsequent lectures about little

11:21.060 --> 11:23.159
Indian versus big Indian and why

11:23.160 --> 11:24.450
it looks like this.

11:25.700 --> 11:26.989
But this is the actual number,

11:26.990 --> 11:28.519
negative 10 stored in two's

11:28.520 --> 11:30.259
compliment, and then we can see that

11:30.260 --> 11:32.210
in Hex in our

11:32.240 --> 11:34.350
listing or the number 20.

11:34.370 --> 11:35.370
So 20 is 14

11:36.200 --> 11:37.019
and hex.

11:37.020 --> 11:38.950
All right. It's a 16 plus a four.

11:40.010 --> 11:41.510
And then we can see minus 30.

11:42.320 --> 11:43.489
So if you want practice on your

11:43.490 --> 11:45.409
twos, complement, pick a number

11:45.410 --> 11:46.369
that you want to do.

11:46.370 --> 11:47.497
So say negative seventy

11:48.350 --> 11:49.624
six and try and figure out

11:50.210 --> 11:52.639
what it's binary representation

11:52.640 --> 11:54.349
is, figure out what it's hexadecimal

11:54.350 --> 11:56.269
representation is, and then go

11:56.270 --> 11:58.399
ahead and convert

11:58.400 --> 12:00.289
it and then build a program

12:00.290 --> 12:01.999
that does it generate a listing and

12:02.000 --> 12:03.860
then you can see what the result is.

12:12.750 --> 12:14.514
So here is an example that I had run

12:14.610 --> 12:15.419
before.

12:15.420 --> 12:17.309
Again, you see the bait, which is

12:17.310 --> 12:18.690
move something into X

12:19.140 --> 12:20.549
and then we have the numbers zero

12:20.550 --> 12:22.169
one, which is the number one.

12:24.940 --> 12:26.499
Additionally, we have commands that

12:26.500 --> 12:28.029
we can run in order to view data

12:28.030 --> 12:30.009
that's in an executable, so

12:30.010 --> 12:31.010
like a listing.

12:31.270 --> 12:33.309
So HSD is going to give us raw

12:33.310 --> 12:34.310
hex by default.

12:34.690 --> 12:36.309
It prints the actual data that's in

12:36.310 --> 12:37.310
the file and also

12:38.290 --> 12:40.269
can convert from its

12:40.300 --> 12:41.623
its output back into binary

12:42.250 --> 12:43.250
if you need to.

12:46.310 --> 12:48.380
So, for example, my executable

12:48.410 --> 12:49.733
is called two point one, so

12:50.270 --> 12:51.559
I can say it's sixty

12:52.370 --> 12:53.370
two point one.

12:54.800 --> 12:56.899
In all of the raw bites

12:56.900 --> 12:58.566
and we can actually see some ASCII

12:58.790 --> 12:59.790
characters in our

13:00.620 --> 13:01.620
file that represent

13:02.570 --> 13:04.236
different things that are included

13:04.580 --> 13:06.169
inside of the binary file.

13:08.330 --> 13:09.740
So that's kind of interesting.

13:12.000 --> 13:13.519
Additionally, we can run object

13:13.890 --> 13:15.359
dump, so this will print off the

13:15.360 --> 13:17.390
disassembly of a binary program.

13:17.400 --> 13:18.899
And so if you have a binary program

13:18.900 --> 13:20.099
that you want to look at and you

13:20.100 --> 13:21.330
want to see the assembly of,

13:21.990 --> 13:22.990
we can run object.

13:23.160 --> 13:24.434
So object dump and then we

13:25.140 --> 13:26.669
are using intel syntax.

13:26.670 --> 13:28.559
So you need to set the disassemble

13:28.560 --> 13:29.760
options to Intel.

13:30.270 --> 13:32.669
The minus D is to do disassembly

13:32.670 --> 13:34.529
and then edit out is the name of the

13:34.530 --> 13:36.059
program that you want to run it on.

13:44.220 --> 13:45.899
So let's go ahead and run it on our

13:45.900 --> 13:46.900
program.

13:51.350 --> 13:52.939
And so you can scroll through here

13:52.940 --> 13:54.559
and you can look at the actual

13:54.920 --> 13:56.750
disassembly of that program

13:57.290 --> 13:59.329
or the assembly that

13:59.570 --> 14:01.469
a or figure it out.

14:01.490 --> 14:03.289
So this assembly is just a program

14:03.290 --> 14:05.419
that is going to go

14:05.420 --> 14:07.070
and convert all of the

14:07.820 --> 14:09.949
the functions and the data into

14:09.950 --> 14:10.950
assembly code.

14:11.480 --> 14:12.950
So we can see here that we put

14:13.460 --> 14:15.529
in our numbers as negative numbers

14:15.530 --> 14:16.880
or positive numbers.

14:17.540 --> 14:19.279
And the disassembly is going to show

14:19.280 --> 14:20.554
us that raw number and not

14:20.570 --> 14:22.639
necessarily the

14:22.880 --> 14:24.769
number in Base 10 that we are used

14:24.770 --> 14:25.770
to.

14:28.620 --> 14:30.119
All right, so in summary, we learned

14:30.120 --> 14:31.884
about assembly language and assembly

14:32.340 --> 14:34.679
instructions, identifiers

14:34.680 --> 14:36.599
and directives, and then creating

14:36.600 --> 14:38.099
a listing of a file and looking at

14:38.100 --> 14:39.929
the contents of a file that

14:39.930 --> 14:41.399
you might have that you want to look

14:41.400 --> 14:42.400
at.

14:43.540 --> 14:44.769
Looking forward, we're going to talk

14:44.770 --> 14:46.387
about logical operators, segments

14:47.350 --> 14:48.350
and functions,

14:49.660 --> 14:50.829
if you have questions, you can

14:50.830 --> 14:52.659
contact me at Miller, MJ, at you

14:52.660 --> 14:54.130
and Keda, Edu, or you can find

14:54.490 --> 14:56.169
me on Twitter at Milhouse 30.

