WEBVTT

00:00.000 --> 00:23.120
Okay, so I'm going to one in every one. Thank you for coming. You're all early birds here,

00:23.120 --> 00:33.040
not me. So this is not going to be a long list about failure. This is not going to be

00:33.040 --> 00:40.320
some standby step to the real. I will try to concentrate on the subtitle and give you more

00:40.320 --> 00:52.480
like an overview of how it feels to write in a assembly in 2026, especially in such a

00:52.480 --> 01:01.120
marginal area as a persistent development. You know that most people writing assembly

01:02.720 --> 01:06.880
most people dealing with assembly are actually reasonably assembly and they are most often

01:06.880 --> 01:15.600
disassembly and some people develop tools that generate assembly, but writing in a assembly is

01:15.600 --> 01:22.160
something quite a marginal activity. Let's be clear, and writing on the operating system in a

01:22.160 --> 01:28.720
assembly is in a more marginal activity and in 2026 that's something, well, a bit strange. That's why

01:28.720 --> 01:38.080
I give you this disclaimer that you can consider it from hobby, art, anything. So if you're here for

01:38.080 --> 01:46.960
serious business, profits, things like that, you can stop using here. Okay, so please raise a hand

01:46.960 --> 01:54.800
to who recognize the guy on this picture. Okay, so this is actually a screenshot of

01:55.680 --> 02:03.840
quite the famous YouTube video where the guy is singing writing, see, writing, see, so I'm trying to say

02:03.840 --> 02:15.520
that this guy writing, see, is wrong. Maybe he's just more practical, but still we'll be

02:15.520 --> 02:23.840
speaking today about writing in assembly in 2026. So yes of course you're aware of some specific

02:23.920 --> 02:32.000
areas and implications like optimization of meta-quadics of maybe some compression and decompression algorithms.

02:32.000 --> 02:41.280
This is where I think you agree that it is still needed and the vehicle even now,

02:43.120 --> 02:53.200
I will be talking about a more niche thing. Obviously I see that quite a few, quite a few guys

02:54.400 --> 03:01.680
old enough to maybe develop your own personal systems in assembly sometimes. There are hundreds of them

03:02.320 --> 03:07.680
and make a thousands so I'll call it a lot more of those systems and they are mostly dead now.

03:07.680 --> 03:17.280
There are only a few survivors still alive today and the caliber of this marginal activity

03:17.360 --> 03:28.880
because we are still alive since 2024 when we worked of miniaturists, our great answer step

03:28.880 --> 03:41.200
written by William Toriyama sorry for my finish. So this minute is not only our answer star,

03:41.200 --> 03:52.880
but it has been our competitor since 2024. You can consider this white heated rivalry maybe,

03:53.680 --> 04:00.800
but anyway, so what is got to be realized? It's again, I hope you have a personal system

04:00.800 --> 04:06.480
quite standard with its requirements. Of course this is just main requirements. If you have any

04:06.480 --> 04:11.920
modern energy 64 processor, it will run on it, at least it will boot then we will see.

04:14.240 --> 04:21.920
If you have a UFI folder, UFI firmware, we have a UFI loader that's available too.

04:24.160 --> 04:34.640
We can see there is a question mark, monolithic work because then the terminology here is a bit

04:34.640 --> 04:41.040
vague. Some people think that if your drivers run in a kernel space, then it's monolithic.

04:41.040 --> 04:48.400
Some people say, well if Linux has modules, then it's not monolithic, it's modular kernel.

04:48.400 --> 04:53.200
But we have multiple drivers too, but I think it's still monolithic.

04:53.280 --> 05:06.560
So it's written in flat assembler, short of awesome, and of course you can use other languages

05:06.560 --> 05:15.040
for drivers, especially for user space applications. On the bottom you can see that we even

05:15.040 --> 05:20.160
participated in Google some of course several times, so this is another sign that

05:21.120 --> 05:26.880
we are quite marginal, but still alive. So maybe this time we will be happy to participate too.

05:26.880 --> 05:31.280
By the way, the deadline to apply for a little summer of course is maybe next Friday,

05:31.280 --> 05:35.680
they're kind of Friday. So if your project hasn't liked yet, come on up.

05:37.120 --> 05:46.800
So let's get to any kernel. Any kernel is a concept that was actually introduced on first

05:46.800 --> 05:55.360
them, but quite a few years ago, by another famous guy, Auntie Kanti. You can check her,

05:55.360 --> 06:02.720
he's a talker on first them, which we just called anything kernel on run kernels.

06:02.720 --> 06:10.000
You can also Google his PhD thesis, which gives more detail on what this is and how to

06:10.080 --> 06:20.400
develop it. Again, some analogy here is a bit vague, and there are similar words for

06:20.400 --> 06:27.920
different operating systems dealing with the similar concepts. The most famous, I'd say,

06:27.920 --> 06:34.720
is of course user won't leave you. You're familiar with it, but other operating systems have

06:34.800 --> 06:43.600
similar concepts too, and so this is why and how we have this in February. This is called

06:43.600 --> 06:53.200
O'Ka or maybe UNKA, like user remote calibre, and in short, the concept is

06:54.320 --> 07:00.880
when you have a monolithic kernel, you run your drivers in a kernel space when you have

07:01.760 --> 07:11.600
microchernally running their domain. User space, so one of the tasks for operating

07:11.600 --> 07:23.760
systems is to abstract hardware for applications. Maybe it's possible to add some layer for drivers

07:23.760 --> 07:31.680
too, and if we somehow make the kernel to run in user space, so maybe drivers will be running

07:31.680 --> 07:38.400
user space too, and if you can build the kernel to run in kernel space, in real space,

07:39.440 --> 07:46.320
you can do it in any way, so drivers can run anyway. What I mean when I talk about

07:46.320 --> 07:51.200
running a kernel in user space, of course it's on top of some other host operating system.

07:52.160 --> 07:57.920
This is not for efficiency of applications, of course, but for testing purposes. When you

07:58.880 --> 08:06.320
compare the bugging, for example, in the new zero, and the bugging in user space, this is just

08:06.320 --> 08:13.520
to completely different models. So if we can move at least some parts of the web independent

08:13.520 --> 08:20.640
parts of the kernel to user space, then development testing on this becomes much more visible.

08:22.160 --> 08:32.160
So let's discuss some myths and truths about assembly, and especially in 226.

08:33.440 --> 08:42.160
There is a myth like people who write in assembly, they all use a CRT monitors with green letters

08:42.240 --> 08:51.040
in the 80s to 25 symbols and the seats, and they don't use any tools to check their code,

08:51.040 --> 09:00.560
they just write it in the hope for the best. Now that's not really the case, because for example,

09:02.960 --> 09:10.640
there are tools for collecting coverage for assembly codes. I will provide you an example later.

09:11.200 --> 09:17.520
There are tools for many different things. Sometimes you don't have tools, but just because

09:18.720 --> 09:24.400
not many people are interested here, and you are the one who developed those tools.

09:24.400 --> 09:32.640
And I was actually the person who had to create quite a few tools for

09:33.600 --> 09:45.200
full-letter developments of any kernel into realized. From these features and tools listed here,

09:46.480 --> 09:52.080
of course, the trace is not available. I'm not going to light you, because

09:53.440 --> 09:57.840
if you write in assembly and you don't have to follow any column convention,

09:57.840 --> 10:06.960
of course the debugger has an idea about how to unwind you stack, but for coverage, for example,

10:06.960 --> 10:13.760
if you collect branch coverage and you know all your branches, then of course, if you know if

10:14.800 --> 10:20.000
any branches taken, I'm not taking, then you can just kind of calculate your light type of length

10:20.000 --> 10:33.440
coverage. So automatic testing, why not? We used to think that some modern things and maybe buzzwords

10:35.200 --> 10:40.960
only at light, the modern technologies, and things like that, but technically speaking,

10:40.960 --> 10:49.440
nothing prevents you from using unit testing and automatic testing and so on for assembly.

10:49.440 --> 11:00.000
So why not? I will show you later how. And actually any kernel here is a concept that helps me

11:00.000 --> 11:08.640
to do all the above, except that trace, as I said, because again, if you have just a user space

11:08.640 --> 11:17.200
application running in your, I don't know, Linux maybe or Windows or a tele, you can instrument it

11:17.280 --> 11:26.000
on source level and maybe use some binary tools, it is not what you have in kernel space,

11:26.000 --> 11:36.080
Windows 0. So here is a map of our kernel files. You don't have to see those tiny names of the files,

11:36.080 --> 11:44.320
what I want you to notice here is that there are clusters of files and they are actually

11:45.040 --> 11:51.040
kind of subsystems of our kernel. And of course, in the connections within each subsystem,

11:52.320 --> 11:59.760
there are much more interconnections inside the outside, and if we try to maybe somehow at the

11:59.760 --> 12:07.440
wrappers to those outside calls, or maybe some stops, sometimes, especially for things accessing

12:07.520 --> 12:16.320
the hardware, then maybe we can move this way, parts of kernel which is hardware independent to

12:16.320 --> 12:25.920
the user space. And to be more specific, this is where we are now. So these are parts of the

12:26.000 --> 12:38.080
kernel, which don't access hardware directly. That's why it was possible to move to the user space.

12:38.080 --> 12:45.840
Of course, a file system is maybe the first candidate for these device drivers,

12:45.840 --> 12:59.920
that keeping this directly harder to move, but file systems, why not? Then graphics UI,

12:59.920 --> 13:12.560
if it's a frame buffer mapped to GPU memory, or if it's just a round buffer, there is no difference

13:12.560 --> 13:20.560
for software, or at least we can make it this way more than transparent for software. Then basic

13:20.560 --> 13:29.840
network, I will mention later, but you know that there are, for example, top and two main

13:29.840 --> 13:39.440
interfaces, where you can create virtual network interfaces, not real, real, not hardware,

13:39.440 --> 13:47.120
network art, so this is how it's done. Quite a few subscriptions. You see, this is, of course,

13:47.120 --> 13:56.320
not the whole kernel, but based on this, even this in user space, this is this easiest development

13:56.320 --> 14:07.520
and the debugging a lot. Yeah, so let me go to the services of host type system,

14:07.520 --> 14:13.760
the links that is in my case, that allows us to move in from the kernel space to user space.

14:15.600 --> 14:21.760
Of course, we don't have, we don't have a Beijing available from user space to well, okay,

14:21.760 --> 14:28.560
let's just use good old ellipse memory routines. Of course, we don't have

14:29.120 --> 14:37.120
access to hard drive and so on. Okay, that's use files. We didn't have network, I mentioned

14:37.120 --> 14:44.640
some top interfaces, virtual parts. Okay, I mentioned demographics too, keyboard mouse,

14:45.280 --> 14:53.600
that's easy to pass through, or you can just pre-record or put something in your file,

14:53.920 --> 15:01.440
replay from a file input, user input, that will be reproducible, so you can

15:01.440 --> 15:07.760
introduce in the bug easier, in the file system, okay, I think you have familiar with file

15:07.760 --> 15:13.520
system in your user space, so actually modern operating systems and the limits in particular provide

15:13.520 --> 15:21.200
quite a few things to do in your user space, what we used to do on the neural space.

15:22.160 --> 15:28.640
So here's a, here are some assembly specific hooks, oh my good, the precious,

15:30.000 --> 15:40.480
that I used to separate parts of the kernel that I mentioned before. Yes, on the convention,

15:40.480 --> 15:45.600
you don't have to comply to any when you're writing assembly, okay, let's let that some

15:45.600 --> 15:53.680
wrappers, I know, then unfortunately there are some static adversities in the kernel, okay,

15:53.680 --> 15:59.600
we have linked with creeps so that it's allowed to address these privileged, privileged instructions.

16:00.320 --> 16:07.600
Well, modern assemblers, I mentioned flat assembler, is not something from half century ago

16:07.600 --> 16:13.760
when we had one pass assemblers, now flat assembler has a powerful gorgeous

16:13.760 --> 16:19.760
pre-processing, you can add the materials, you can add to complicated service,

16:19.760 --> 16:27.120
it's scripting, so population one instruction with nothing, flat forward. It's okay to have

16:27.120 --> 16:33.360
some dead code and just don't, don't call it, if it's some real mode code and don't call it.

16:33.360 --> 16:38.080
Of course, if you don't call it, you don't test it, but most of the kernel is not real mode.

16:38.160 --> 16:50.160
So, yes, I mentioned first pre-processing. Here we go to the binary analysis.

16:51.520 --> 16:57.360
There is a weakness, obvious of assembly that it is tied to some specific architecture,

16:57.360 --> 17:06.080
but from that, besides on that hand, this allows us to use some instructions, such extensions

17:06.160 --> 17:12.960
that are specific to this CPU. For example, if we go to coverage, which I mentioned,

17:13.680 --> 17:20.320
there are four, at least four, I'm aware of extension size extensions, it's allowed to

17:21.600 --> 17:27.280
actually collect coverage or get information about branches taken, not taken.

17:29.120 --> 17:34.560
I used the very first one, the generic one, which is available in all

17:35.520 --> 17:48.800
x86 processors. It works very, very straightforward. You just set up one of MSRs, you set one of the

17:48.800 --> 17:58.560
flux in your iflex registers, and then when the branch is taken, you get an exception on the CPU level,

17:58.560 --> 18:08.560
and in user space, you just get your signal handler called, and this is how you can collect

18:09.360 --> 18:16.160
branch coverage, and then you can calculate the length average. So, quite straightforward.

18:16.240 --> 18:30.000
And you can see on this picture how this coverage looks like. So, there is column with 119,

18:30.000 --> 18:41.440
and this is the number of times, typical line was executed, and if you see one number on the left,

18:41.440 --> 18:47.760
then this is a number of times the branch was taken on a taken. So, for example, one of branches,

18:47.760 --> 18:57.680
the conditional branch on top was taken on a taken taken, but the branch below has never been taken,

18:57.680 --> 19:04.000
so there was no error. By the way, you can see that there are no magic numbers. This is assembly,

19:04.000 --> 19:12.880
but no magic numbers, not much things are hard coded. Maybe a macro for SDD code, which is

19:14.320 --> 19:22.160
okay, which is actually some coding convention, that's something. So, let's go to the tools.

19:23.040 --> 19:35.120
I build around this uncle, one of them is uncle shell. It's both interactive shell,

19:35.120 --> 19:43.760
and it can be not interactive when you make it through the comments from a file. So, that's how our

19:43.840 --> 19:49.840
tests are done, just a file of pre-recorded instructions and that's it.

19:53.360 --> 20:02.880
This is an example of file system functions. It just attaches one disk and

20:05.120 --> 20:10.880
gets information about the directory and a file. So, the very straightforward, and if you have

20:10.880 --> 20:18.480
a familiar with the tools developed for such a file system as XFS, or maybe for X,

20:19.440 --> 20:29.760
then I believe that this concept is a familiar to you, but you can use your file system code

20:29.760 --> 20:37.520
on image files, not on devices. There are, of course, more comments just to name a few,

20:37.600 --> 20:45.280
not only about a file system, but for that work, for example, for keyboard and mouse input,

20:47.040 --> 20:56.400
for many other things. For example, you can set your screen resolution and before boot, and then

20:56.400 --> 21:02.800
boot different environments. So, you can have the right access to this Cisco entry.

21:07.520 --> 21:15.200
Another tool is OmkaFuse, which actually is similar to the previous one with shell,

21:15.200 --> 21:20.320
but the shell was written in the comments from its standard input. You could type it in or

21:20.320 --> 21:27.360
read from a file. OmkaFuse gets input comments from a few file system. So, you actually

21:28.320 --> 21:39.440
mounting an image file system image using the kernel code, assembly kernel code, but this

21:39.440 --> 21:50.640
is running in a user space, and then you can just walk the tree of a file system image using

21:50.640 --> 21:59.840
your Linux shell and do like CD sampling or tree sampling, very real stuff, not the bugger's nothing.

22:01.680 --> 22:10.240
And of course, the final, the most sophisticated tool is OmkaFuse, which is actually

22:10.560 --> 22:20.320
kind of a kind of a calibration kernel, which runs in the Linux user space. And the most

22:22.560 --> 22:28.800
impressive for me detail is that even tax eviction is working. It's done by a signal handler.

22:28.800 --> 22:37.360
Of course, if you have something like network, which is sensitive to timing, then it will not work

22:37.360 --> 22:50.560
of course. But, we used to have multi-threaded kernel in Winx0, and now we can have it as a simple thread

22:51.440 --> 23:00.960
in the user space. And those kernel threads used to be in Winx0, they are switched

23:01.440 --> 23:10.240
like the lightweight threads, you name it, but for Linux, it's just a simple thread. You can

23:10.240 --> 23:20.160
debug it in GDB, you can run several instances of it in parallel. What I first thought about

23:20.160 --> 23:27.920
this, it's not going to happen, but it's happening. And you can see a window here, it's one of

23:27.920 --> 23:37.840
our tests, it's basic graphics stuff. You can see even a cursor and a arrow on the top left.

23:37.840 --> 23:45.600
So, actually, if you use one of the comments I mentioned before, move mouse, you can even move

23:45.600 --> 23:55.200
this cursor to the edge of the window. And another thread, the kernel thread, will change your

23:55.200 --> 24:04.160
arrow cursor, so the cursor with two arrows, which you can usually see to resize the window.

24:04.160 --> 24:14.160
So, this is what usually happens between user space and kernel space on hardware, but here it

24:14.160 --> 24:23.200
is everything in user space as a simple thread. So, a feature directly, the directions are quite

24:24.160 --> 24:31.600
straightforward again. I'd like to finish that ML-13 is better, because it's hard to find the

24:31.600 --> 24:39.600
hardware that runs acceptable without an ACPI. Of course, there are more features in file

24:39.600 --> 24:47.920
systems, to implement this very lightning issue too. We can go further with the USB over a

24:47.920 --> 24:57.200
USB, just like file HTML user space, why not? So, this struck the conclusion that I started

24:57.200 --> 25:03.600
with audio player, but I needed some part there, I needed...

25:04.560 --> 25:11.600
Yeah, so thank you. Thank you. Thank you, thank you.

25:11.600 --> 25:19.600
Thank you. Thank you very much. Thank you.

