Hi there. Thank you so much for joining me here at GitHub's Con, where I'll be discussing applied GitOps with Argo CD Autopilot using multiple clusters and an application set. My name is Hannah Selickson and I'm a developer advocate at CodeFresh, which is a continuous deployment platform that supports both GitOps and Argo deployments. However, prior to being a DA, I spent several years as a .NET developer writing C-Sharp and primarily designing and building REST APIs for the insurance industry. Later on, I took on a role as such as a COE lead, which is essentially a center of excellence lead. I made sure that our developer organization had the right tools, resources, and trainings to execute their tasks efficiently. This also included vetting tools, monitoring workloads, and then reporting back to our VP of IT, management, and CTO with data that I either proved that we were working quickly and efficiently, or we wouldn't, and we would have to come up with solutions. So this is why I'm excited to be on the other side of the table nowadays, sharing with others these tools that can really help you. So today, we're going to talk about why organizations are implementing GitOps to their deployment process and essentially what does that mean. And then we're going to identify some of the challenges that these organizations face when they are applying GitOps to their workflow. Then I'll introduce you to Argo CD Autopilot. We'll explain how it works and how it can help those organizations who are utilizing GitOps and using Argo for their deployment process, and then we'll give a brief demonstration. So the infrastructure management growth. First, we start out with our programmatic automation, and this includes like your PowerShell, and then we evolve into configuration management, infrastructure code, and then GitOps. GitOps is becoming an essential part of the cloud operating model. It promotes DevOps best practices to the management infrastructure, to improving the speed and quality of your infrastructure service delivery, and maturing infrastructure operations. Making GitOps part of your cloud operating model enables you to standardize application and infrastructure management processes, driving both from definitions stored and version controlled repositories. So essentially your source of truth. The shortage and popularity of GitOps is due to the desire of speeder application deployment cycles. Organizations today want to be able to deploy their new features as quickly as possible to their customers. This improves business, profitability, and it makes everybody happy. So as a result, an increasing number of businesses are expressing interest in using this framework just this year in 2022. GitOps is attractive because there's a small learning curve. It's fairly easy to set up and it can be adopted pretty easily. It allows your teams to work faster, deploy their own code without the need of a heavy operations team, all in tandem with having boundaries put in place to ensure that those devs don't go breaking things and make unauthorized changes to your infrastructure. Plus it's important to mention that because just because you store your manifest and Git through your manifest file in your Git repository does not make your framework GitOps. Sorry. GitOps combines an orchestration system, Kubernetes, and your source control system with a monitoring software. This is to ensure that we create a close reconciliation loop in which an application running in production should always match its desired state. This is recorded in version control and your source control. Therefore any deviation between the two will be detected automatically. So in today's evolution, tech industry cannot afford to wait several months to release a new feature and get in the hands of your demanding customers like I mentioned before. GitOps provides business value to those who adopt it. And regardless of your size, big or small, based on the fact that cloud applications can be updated faster without compromising the security or the stability of their infrastructure, the benefits of doing this can sometimes be overlooked just due to ongoing debates of legacy ways that lots of us can relate to when it comes to bigger organizations with clunky legacy systems and an outdated culture. However, based on research such as the DevOps research and assessment group, aka your Dora metrics, there comes several organizations have found that when it comes to delivery for a Kubernetes or cloud app, there are four major variables that determine this organization's success. And those are described as your software delivery and operation performance measures. It's these four measures, frequency of deployment, lead time for changes and updates, mean time to recovery, and your change failure rate, which is otherwise known as the proportion of changes or updates that fail. With GitOps, it's a sure way to improve your organization's effectiveness against all those four measures, metrics that are providing critical and many business to market share and profitability. So now that we've really kind of proved that, hey, applying GitOps to your workflow can really improve your business, your profitability, and also probably the happiness of your organization and your teams and how they work because they're working much more efficiently. But when you apply GitOps and you're starting to explore best practices and making sure that you're executing this properly, there do come a lot of challenges. And those challenges can really be as simple as how do I handle multiple environments and apps and multiple clusters when I've containerized all of these services and now I'm using a CI CD tool and I don't know how to do this. Also, when I need to promote changes to those multiple applications and I need to also utilize different clusters, it can be a little tricky. So maybe what you need to consider when you are thinking about these challenges are essentially the time constrained engineers who are performing a lot of these tasks manually and just how expensive and inefficient that can truly be because the effort in transition to a GitOps workflow is super appealing. And you also have to consider like your testing and gatekeeping and your regular maintenance processes that can lead to really expensive and also preventable environmental issues and additives for your organization. So this brings up a question. How do we begin applying GitOps to our deployment process so we can deploy more frequently and reap those benefits? So it's no surprise I'm mentioning Argo is it? Argo is one of the most popular tools in the cloud native space and has continued to experience rapid adoption. Argo has built in a GitOps flow and so that's why it's so appealing to organizations when they begin this shift in their culture and in their processes that they utilize Argo. And I want to point out two major concepts when it comes to Argo. First it's their application which an Argo application is essentially what connects a namespace within your target Kubernetes cluster with the declarations of your desired state and your Git repo. And this can be done by defining a lot of your configurations within a raw manifest, a home chart or a customized overlay. And then the second major concept I want to mention is a project. A project in Argo CD allows you to group your applications which is useful when your organization has multiple teams. However, I also think of project as environments such as it could be regional, it could be your staging, your prod, and this is what's allowed you to restrict what can be deployed and restrict what apps may be deployed to such as your destination clusters and namespaces. I don't want to get too thick in the weeds about these two concepts. However, these two major components of Argo allow organizations to begin deploying their cloud native apps with GitOps quickly and efficiently. So let's take a second to identify some additional challenges when organizations are beginning to utilize Argo. So two questions organizations have once they're on the GitOps bandwagon and they're using Argo. How do we structure our directories? How can I enable Argo CD to manage itself? When organizations are first adopting GitOps and begin leveraging open source projects and tooling like Argo, these basic concepts make others feel blocked and it's because there's no one way to do any of these things. How do I structure my directories for multiple apps and environments? What structure will work best if I need to promote changes? And then also raises the question of how can we install Argo CD so it manages itself or how can we install Argo CD in a GitOps way? Because honestly trying to manually set up a way for Argo CD to manage itself is not easy because essentially what you want to do is you want to use Argo as your orchestration engine because it'll be nice to let it rule itself through your Git repo. Then it enables automation so that any change can show up on your cluster. So with these challenges there's a way that we can kind of just at least have a foundation to answer them or we have at least a roadmap that we can follow and that's when I bring up Autopilot. Autopilot is an open source project for the Argo community that provides us with a tool to bootstrap Argo CD. It also includes an opinionated GitOps setup for your directory structure. And one thing I'd like to clarify about Autopilot is that it is not a replacement for Argo. It's simply an installer you can use to install Argo in a GitOps way. So as I mentioned this tool offers the opinionated way for organizations to kick start their GitOps continuous deployment process and allows them to add applications and simplify the process of promoting changes across those environments. It also has a friendly command line tool for bootstrapping Argo CD on the clusters, setting up your Git repos, managing applications across environments, and even simplifying disaster recovery. You can easily set up one-off environments or staging environments and promote changes across those in a straightforward GitOps way. So how does Autopilot do this? Well, like I mentioned, there is a bootstrap command that you can execute that allows you to do this. And Autopilot saves operators times by installing and managing the Argo CD application using GitOps, providing a clear structure of how applications are added and updated, all centralized from Git, creating a simple pattern for making updates to application and promoting those changes across environments and enabling better disaster recovery by being able to bootstrap new clusters with all the applications previously installed. Autopilot is a tool which offers the opinionated way of installing Argo CD and managing GitOps repositories. So how does it do that?  This application will manage the Argo CD installation itself, so after running the command, you'll have an Argo CD deployment that manages itself through GitOps. From now, we're going to use a concrete project and applications that will launch it up, and Autopilot will commit the required manifest to your cluster. So once committed, Argo CD will do its magic and apply the applications to the cluster. An application can be added to a project from a public everybody or have the recommended local file system on your machine. Autopilot will also communicate to the cluster directly, only during the bootstrap bits, and this is when it deploys Argo CD. After that, most commands will apply access to your GitOps cluster, and when your object will launch an application, your remote cluster, the Autopilot will apply access to Argo CD server. So let's see that bootstrap command in action. So once committed, Argo CD will do its magic and apply the applications to the cluster. An application can be added to a project from a public Git repo or a path or directory in your local file system on your machine. Autopilot also communicates with the cluster directly, but only during the bootstrap phase, and this is when it deploys Argo CD. After that, most commands will require access to your GitOps repository, and when you're adding a project or an application to your remote cluster, the Autopilot will require access to Argo CD server. So let's see that bootstrap command in action. Just give me a moment. Hi. All right. So what we're going to do now is we're going to start by executing the Argo CD Autopilot bootstrap command. And so what this is going to do is it's essentially going to create our directory structure in our GitHub repo. And I've already assigned my GitHub repo, as you can see, and I also provided it with a token so that has access to this. So now I'm just taking a look inside my repo where you can see the directory structure here that I had mentioned before. We'll just take a look. This explains how to create an application. And within this bootstrap Argo CD customization file, this is where we're defining our resources. I'll just take a look in here now. These are our cluster resources. And this is going to be the Argo CD YAML file through this folder, your root. Okay. And this is where our projects are defined. And it gives you an example of how you can create a project. Now let's get back to the terminal. So when we complete the bootstrap command, it provides us a cube cuddle port forward command that we can use to then access the Argo CD UI. It also provides us a password that I can then use and sign in. And now you can see essentially everything that we just created and just saw within my repo. So as you can see, Argo CD is able to manage itself. Now with that command, I just created a project for prod. I'm going to go back into our terminal. Now I'm going to install an application and assign prod to it. Looks good. Now I'm using a different cluster and I've created a project for staging and assigned the application to staging. This is now completed. Now we're going to take a look at the UI again and you'll be able to see my other application for staging, still synchronizing. Then we'll take a look at the project so you can see the staging project. There we go. Okay. And so this is just a brief example of how you can use multiple applications, multiple apps, multiple environments. Fortunately, I don't have time to get too nitty gritty. But this is just a brief demonstration to show you how autopilot works. Now we'll take a look into our file structure. Okay. Yep. There's prod and staging. Awesome. Thank you everyone. So here's an example of a directory structure with Argo CD autopilot. I'm including a demo app and two projects and overlays for staging and production environments. However, whenever bootstrap command is executed, autopilot provides the following for you. A bootstrap folder which contains all bootstrapping resources as shown and root.yml file which contains your application definition for projects folder, a project folder which is essentially a logical grouping of applications. It's this project folder that can actually be used as a different environment like I mentioned for your staging, your dev, qa, prod. You also have a cluster resources.yml file and this is an application set controller managing your cluster resources folder by pointing the cluster resources in your cluster.jsm file. It uses Argo CD, git generator file and manages the Argo CD namespace in your Kubernetes cluster. An Argo CD.yml is an application definition to self-manage Argo CD itself. So autopilot also has tons of commands which you can use to add new projects and application, which is why I mentioned those earlier. It creates and commits any changes made to your GitHub repository or whatever repository you're using and ensuring that your desired state is applied by the Argo CD operator. So now as you can see within my structure, I have multiple environments and for this demo application I can also create additional applications and leverage different clusters. But how? Well nowadays Argo CD incorporates an application set with its installation. So what is an application set? Well, unlike an Argo CD application resource that deploys resources from a single git repository to a single cluster or namespace, the application set expands this functionality. An application set uses a template automation to create, modify and manage multiple Argo CD applications at once, while also targeting multiple clusters and namespaces. The application set controller is now installed alongside with Argo CD within the same namespace and it creates multiple Argo applications based on the application set custom resource. This is what ensures that your Argo CD app remains consistent with your declared resources. And it essentially takes the application set and outputs one or more Argo applications. Well, fun fact, something I didn't realize when I submitted my CFP for this talk was that Autopilot incorporates an application set and applying this pattern doesn't need to be a separate step when you need to create multiple apps. So before I learned about this tool, I thought wouldn't it be great if we could apply an app set after we install Argo CD to set up our directory? Well, the maintainers of Argo CD and the community agreed that hey, it would be really helpful if we could install app set when we install Argo CD because we all are working with multiple apps. Oops. So now that you've had your crash course of Argo CD Autopilot and seen a demonstration of how it works, let's review some of the benefits. Autopilot provides an opinionated way to build multi-project, multi-application system using GitOps principles. It also creates a new GitOps repository or you can still use an existing one that you have. It supports creating the entire directory structure under any path that you require. When adding applications from a public repository, it also allows committing as either a customization that references the public repo or as a flat manifest file containing all of your required resources. And you can use a different cluster from the one Argo CD is running on as a default cluster for a project or a target cluster for a specific application. So Argo CD Autopilot is still under active development and you can find it under the Argo project Argo Labs. And feel free to check it out, learn more about it. You can also check out some existing issues and find ways to contribute. I really hope that this helps you and your organization get started with your GitOps workflow and makes things a little bit easier or at least provides an opinionated way of how you can move forward. Thank you so much everyone. Have a great day.


Hi and hello to everyone. I am Ganesh, History Faculty at Shankara's Academy. I hope everyone is safe and healthy. In this present situation where the COVID-19 is spread across the globe, I think this is the right time to discuss about the history of the pandemic. The diseases have ravaged the human civilization and humanity. Even it pushed the human civilization to the near end, but it was not so. The human civilization have continued its progress till date. Let me go to the video session that is the history of the pandemic. First, we need to know what is mean by pandemic. Pandemic means the spread of a disease to a wider geographical region is called as pandemic. For example, COVID-19, which is spread across the entire globe. That's why it is called as pandemic. Very recently, in the northeast of China, in a place called Hameen Manga, the Chinese archaeologists have excavated the place. When they excavated a particular place, they were shocked to see a lot of human skeletons are found in a particular place. When they examined those human skeletons, those skeletons were invariably of young, middle and elderly people. So, they took the samples of those skeletons and the soils of those place and they put it further investigation. They found that because of some kind of disease, the people have put the dead bodies in the particular place and they have abandoned the place 5000 years before the birth of Jesus Christ. So, China is the country which was known for prehistoric epidemic in the world. Next, the plague of Athens. Here, plague means disease, not plague disease. In those days, diseases is also called as they mentioned as plague. In present Greece, 500 years before the birth of Jesus Christ, there were two kingdoms. One was Pata and the other one was Athens. These patterns on Athens were always war with each other. So, the Athens people, in order to protect the people and the city from the Spartans, they built a huge wall around the cities to protect themselves. It was called as long wall. On one of the occasions, the Spartans went for war with the Athens. When the Athens came to know about the arrival of the Spartans, they went behind the wall. The siege continued for many months. Quickly, among the Athens people and the Athens soldiers, they felt their head was heated, they felt the fever in their body, their throat and tongue was inflamed. Quickly, death was fallen over them. This kind of disease was spread quickly among the entire Athens people and the soldiers. The disease spread to the entire Athens city. It continued for few months. The Athens people were died because of this, including the Athens soldiers. Because of this disease, the Athens soldiers were dying and the Athens army was weakened because of this. This was came to know for the Spartans who were waiting outside the war and they break the walls of the Athens and they entered into the Athens city and they have destroyed the Athens city and killed all the Athens soldiers and the people and they captured the Athens city. So, one of the factors that was responsible for the fall of the Athens was this disease and that was a victory for the Spartans. In the later time, the scientists want to know what kind of disease that it was but they cannot able to identify particularly what is a kind of disease. They felt it may be a viral disease which was spread among the Athens people which was responsible for the fall of the Athens city during the time. Next, the plague of Justinian. In present Turkey, 600 years after the birth of Jesus Christ, there were an empire called Byzantine Empire. It is also called as Eastern Roman Empire, simply called as Vons. Its capital was Constantine in Opel which was ruled by a king with the name Justinian. Near the Byzantine Empire, there was another empire that is called as the Sarsenian Empire or the Potion Empire. The geographical countries which present covering the Byzantine and the Potion Empire was Central Algeria, Tunisia, Libya, Egypt, Israel, Lebanon, Syria, Turkey and Southeast Europe. This was the Byzantine Empire which was existed before 600 years and the Sarsenian Empire was half of Iraq, Iran, Afghanistan and Pakistan very near to the industrial world. This was the Potion Empire. This Byzantine Empire and the Sarsenian Empire was always with war with each other. On one of the occasions, the Byzantines that is Romans, the Romans went for war with the Potions. They defeated the Potions in the war. In Persia, they collected lot of valuables like gold, silver, most particularly the Romans where collected the food grains from the Persia. On their way returning to Constantinople, they collected food grains from Egypt and they went to Constantinople. They victoriously entered into the Constantinople. The celebration continued for months in Constantinople and they don't know. They were carried a disaster within themselves. Disaster, what they carried within themselves was a disease of plague because of the rats which was present in the food grains that was there in the food grains. Constantinople was one of the urbanized cities during the time. Delhi, Mumbai and Chennai and densely populated region. The rodents were hovering there and the rodents spread those diseases among the common people which was densely populated in the Constantinople. Quickly, the plague spread among the Constantinople people. From the Constantinople, it spread to the rest of the Byzantine Empire and the nearby empire of the Sassanin Empire. And day by day, the death was mounted in the Constantinople and in the Sassanin Empire. The church conducted the special prayers and but it was unable to control the disease. Day by day, thousands and thousands of people were died because of this plague. This plague was considered to be as a first pandemic in the history. Because of this, what happened in the history was the economy of the Byzantine Empire was weakened. And because of this, the Iranian Empire was also weakened because of this one. So, this plague disease had completely weakened the empires of the Sassanians and the Byzantine Empire. Next, the Black Death. The first world pandemic and also the most which brought disasters to the world which was spread in the 14th century. The origin point of this Black Death was from the Central Asia. The merchants and the traders carried the goods from the Central Asia and they reached the Black Sea. From the Black Sea, they carried on the ships to Constantinople. From Constantinople, they carried on the goods to ships in the Mediterranean Sea and they reached Italy through the city of Naples, Rome, Venice. From there, the goods were distributed to the entire European continent including Great Britain. In the goods which was distributed by the traders and merchants, the plague disease was there because of the rats. And it quickly spread across the entire European continent. It almost started from 1347 and it continued for many years. And due to the spread of this plague disease, each and every city had that quarantine. The traders merchant had to have, when they come to the city, they have to quarantine themselves for 17 days in the city. But even though they put a lot of restrictions for the traders and merchants and quarantines for the traders and merchants, it was unable to restrict the spread of the disease to the entire European continent. And the people died because of this plague disease. This plague has a size of a tennis ball size in their body and when they burst out, the blood started to ooze out from them. And quickly it brought death to the people. Every city faces the death because of this dreaded plague disease. Even the church conducted the special prayers for this but it was unable to control the spread and the death of this disease. Every government appointed a doctor that was called plague doctors. And that plague doctors have a peculiar type of mask to protect themselves when they were treating the plague patients. It was a birds beak-like mask. In that beak, either they have a scent to overcome the smell or they have medicine to overcome the infection. That mask is still protected in many of the European museums even today. And what change is brought by this plague in the human history? Half of the world population were died because of this plague disease. There was no human to work in agriculture field or work there in the factories. Because of this new inventions and discoveries were emerging in the 15th and 16th century. Those inventions and discoveries laid the foundations for the modern machines. And that modern machine age we called it as an industrial age. That is what we called it as an industrialization. So because of this black dead that it resulted in the form of an emergence of the industrial ages and the industrialization in the history. Next, the American plague here. The American means North America, Central America and the South America. All these were collectively called as Americans. This American plague was spread in the North, Central and South America in the 16th century. In those South America, Central America and North America, many indigenous peoples were lead. They were the Inca emperors, the Mayan emperors and the Aztec emperors. These were the civilization which was existed there. Around 15,000 to 1550, many Europeans started to migrate to the South America, Central America and North America. And they came to settled there. Those indigenous people like Aztecs, Mayans and the Inca people have welcomed those Europeans who came as settlers there. They give a lot of valuable gift to those European settlers but they don't know. Those Europeans are carrying a disaster between themselves. These Europeans who came settled there. A few of the people have cluster of the European diseases like smallpox, chickenpox, tuberculosis, malaria and many other diseases. We know that the tribal people have less immune system and they are very vulnerable to any diseases. And these outsiders that is the Europeans came and settled there. Quickly the infection got into the tribal peoples and it spread among them. Within a century, half of the entire indigenous peoples of the North America, Central America and South America were died. And it was very easy for the Europeans to capture the rest of the people and they made them as a slave and they captured the North America, Central America and South America. As a result of this disease, North America, Central America and South America become colonies of the Europeans. That is a colonization of the Europeans in North America and South America. Next, the Spanish flu of 1918 to 1920. It was spread during the time of the World War I. We know that the World War was the first war which was solved by the human civilization. A major war which brought a lot of disasters to the human civilization. In the first World War, the soldiers were fought in the trench. That was a small trench-like area where the soldiers had to sleep there and they had to fight there. The life of a people was there in the trench itself. During the time of the war, thousands and thousands of soldiers were wounded and a lot of infections was within them. Another thing was, the soldiers were restricted with a small amount of food. The food was rationed to them. They were not fully nutritious among themselves because of the ration of the food. Because of this, the immune systems of the soldiers were very weak. And the less immune system because of the malnourishment among the soldiers resulted in the form of the food among the soldiers. The flu was first pointed out in the American soldiers. From the American soldiers, it was spread to the entire European soldiers. And from there, it spread across the Middle East and Asia. When the First World War was near to the end, the entire world was spread with the flu. And that was a Spanish flu. By the end of the Second World War, by the end of the First World War, the Spanish flu was spread across the entire world. Every girl had a lot of restrictions for the people during the time of the Spanish flu. That was to maintaining the social distance, maintaining the personal hygienic system. When they came out of the house, they had to wear a mask to protect themselves. Even the government had a public notice issue where the schools, the churches, theaters and private halls and their amusements were completely closed on until further notice. Why this name Spanish flu was there? Is it because of bad thing? Everyone thought that because of Spain, this flu was spread. No, that it was not. That is wrong. During the time of the First World War, lot of restrictions was for every country. Spain was the only country where freedom of press was there. They liberally published about the flu. How the death count was there? Because of this, it was called a Spanish flu. Next. H1N1 swine flu of 2009, 2010. The swine flu was one of the pandemic. It was spread from the swine, a viral like infection, and it was spread among the human population. Any people who have a symptom, lost of appetite, have high fever, headache and muscle pain. Even they have a running nose, nausea and diarrhea. These were the symptoms of the swine flu. The origin of the swine flu was from Mexico. It quickly spread from Mexico to the North America and South America. From North America to South America, it spread to Europe and Asia and Australia. So it was one of the epidemic which was considered to be a pandemic in the 21st century. Even not only this swine flu, even we have the Zika virus and the Ebola virus, which is also considered to be a pandemic. The diseases have completely pushed the civilization to the near end of that brick. The human civilization have never bogged down of these devastation. It always bonds back and continued its progress till date. Thank you for watching this video.


Hi, everyone. My area is open government data, so we'll take a slightly different approach. I'm going to give you four emerging issues in New Zealand in this space and then celebrate some open source and some open data successes here in New Zealand. Right, we need champions in our open government data programme. In fact, all of our open cross-system government programmes. So, on the data supply side, we have champions at executive level in each government department and an increasing number of Crown Research Institutes and Local Government across the wider public sector. And they've got a critical role. They have to translate. They have to explain to their peers and their executive teams and then lead in their agencies in translating these words, open data that we've been talking to today, so that data release can become a business as usual activity in their organisations. So, they've got to explain why we do it and why do we release open government data for economic benefit, for social growth to illustrate and transparency and democracy and now people to engage in government activities and of course to be more efficient. So, they've got to use those words, not the words that we policy wonks tend to use within Government ourselves. So, we're translating with those champions. So, they're really, really special people and they also have a role with the users of the data. So, we need champions on the outside of government, people telling us what data that they want and we're not doing very well at that. We're pretty ad hoc, so we're really wanting you to help us improve our act in understanding what you, the users are wanting Government to focus on. So, that's champions. And the next emerging or continuing issue is collaboration. So, open data, sharing, reuse are currently top of mind across Government. There's heaps of information-related programmes on the books at the moment. At the launch last night, as someone was saying, there's 12 programmes going on at the moment. Well, I think that there may be more than that. And they're generally distributed across different departments to share the leadership and the uptake and the financing of those programmes. So, everyone leading them must work together constantly. They must share their drive, their enthusiasm, their smart thinking. The motivations and environments might be different. So, the more they collaborate, the more they understand whether those differences are actually important. And critically, they too must collaborate with you, the users who want to use the open data. We all have to do better. We all have to collaborate more. And that should go some way towards developing common language and definitions and achieving common results. So, that's the next emerging issue. Now, we've got a prioritised policy development as I understand it. There's no official government-wide position on governmental open-source licensing of software it owns. I understand there's been no strong demand for this policy work. So, again, I welcome feedback from you on whether that is the case. The most current policy at the moment is the New Zealand Government Open Access and Licensing Framework, which recommends the use of Creative Commons licenses when copyright works and other material are released for legal reuse. And the NZ goal applies to data sets, but not to software. So, if an agency owns and may wish to release open-source software, it recommends that open-source software licenses be used. And there are departments doing that, like National Library Internal Affairs and Revenue and Land Information New Zealand. And looking at common definitions, we welcome the discussions that have been held by the OpenNZ list about open formats. And we're working collaboratively with them and OpenNZ on updating our guidance on open formats. Apparently, we got a bit wrong and we have to do better. And we need to have results which receive less criticism. So, we need to be commonly understanding what policies needed and then working together to get it right. In terms of getting things right, we do have open data and information management principles which were developed with the users, particularly with NZ Open data ninjas. So, we heard this morning that the default for government is closed. That is not the case. The default for government is open. Let's see the first tick up there. Government data and information is open unless it must be protected. In which case, look at the second tick, it then must be protected. And that covers privacy, personal information, restricted confidential information. But other than that, it's extremely necessity, government information is open. So, if you want to look at those principles, go on to ict.gov.nz. Now, the last emerging issue is having a common course of action. So, enabling us all to prioritise the open data and open government work across the system. So, our open data programme which I advocate is a key element of all of this work. It's key for the data futures forum work. It's key for the open government partnership. It's key for the ICT strategy and action plan and other work across the public sector. So, we, the programme, are pulled in many directions. The open government partnership needs us to engage more effectively with civil society. The data futures forum wants us to expand our programme to cover private sector open information. The ICT strategy and action plan wants data and information to be managed as a strategic asset for the benefit of investment decisions. And the global open data barometer which assesses open data programmes across the world, they want greater evidence of our work with entrepreneurs and civil society and much better release of data about publicly funded contracts. So, prioritising and using our small resource as well is a constant balancing act for us and we need help in deciding what our common course of action is. And just picking up on the data sets, we do very well. We've been rated third out of 86 countries. I think we were just one point behind the second which was the US. So, all those green data sets are where we're doing well. But, as I said, we're not good at releasing our data about publicly funded national contracts. That's the red one. And the orange ones, we could do better with elections and environmental reporting, health and schools performance, what time tables. So, should we prioritise this work over the other cross-government programmes I've mentioned? It's a balancing act for us. So, let's celebrate success. And just before I talk about data.gov.nz, there are lots of government examples on GitHub. For example, Land Information New Zealand who generously host our programme and thank you, Lynns, for having us there. They, I believe, Lynns were the first government agency to release open source software on GitHub. And they're the first public service tenant of the Catalyst Cloud, which is the only fully automated cloud solution available in New Zealand. And that's being used for crown property disposals. Now, I'm terribly proud that data.gov.nz, which is a Department of Internal Affairs website and which publicises New Zealand open government data made available for legal reuse. It uses open source software in the form of the common web platform offered by Silverstripe. Well done, everybody. There's 31 agencies using the common web platform which covers about 70 websites. And there's other open source CMSs that are being used, such as Drupal, and I understand both groups are collaborating, working together. So, just a praise for data.gov.nz. They've just updated it. Have a good look at it. You'll see 2,980, I think it is, data sets up there now. And around other other softwares, the Mahara is used by about 3,000 New Zealand schools. It's the e-portfolio for students to showcase and share their work provided by the Ministry of Education. And the Suppeljack metadata harvester is a fantastic talk that has been developed by Digital New Zealand. They use it to manage harvesting for more than 200 data sources on a 24-7 basis and it supports more than 10 million external API queries a month. And those are from Digital New Zealand. Well done, Digital NZ. Here's an example of Valuad using open-government data and open-source tools, such as PostGIS and QGIS. It's ThunderMaps, an alert service using location data. And at the front there, you'll see that my colleagues had an alert centre him about a problem on his route that he takes when he goes home. So, they've put their data on GitHub and they enable crowdsourcing, and they're also moving into this private sector open-data space that we've been encouraged to work in as well. So, alerting for sale, for rent and flatmates wanted on trade meet. So, that's just a flavour of open-source excellence and just moving quickly to our open-data cases. We prepare, we've done 26, which we think is pretty good, but it's just a drop in the bucket in terms of understanding the impact of open-data release. As I said before, there are high-level benefits for the economy, society, transparency, efficiencies. And we prepare these, put these up on ict.gov.nz, and they are the reasons for our work. If people are not using this data, well, we have to query whether, in fact, the program to release it has been worth the effort. And I'm absolutely certain it has, but we need to know from you how you are reusing that data. So, please come back, talk to me, talk to other government people here about how we can better do with the data. So, open-data open-source are contributing to a more open society in New Zealand. And those emerging issues of championing, collaborating, using common languages, having a common purpose, they all have equal status in my view, they must all be addressed, and let's all commit to these as our contribution to achieving a more open society in New Zealand. And I'll just finish with Rag, I think I should call it. We were rated fourth equal out of 86 countries for our open-data program, and we had been fourth in the first analysis also. So we're doing pretty well, but we can all do better as I've just indicated. Thank you.


Hello everyone. This is a recording for CSE 545 spring 2016 and this is a lecture for the Wednesday class that I unfortunately will not be able to be there, but I know you're missing me just as much as I'm missing you, but due to the magic and beauty of technology we don't have to skip a beat in our class. So we're going to start right where we left off on Monday. So on Monday when we left off we were talking about how we had first begun our investigation into x86 and the x86 language. So first what we looked at was not the language itself but the actual x86 machine. So the important things there for the machine are what are the registers, how many registers does it have, what are the size of addresses in the system, how do we address memory, how are data values stored in memory with the end in this. And so now we continue our x86 tutorial and study and now we're going to look at the x86 assembly language. So here, so the x86 assembly language is how we write programs in x86. So the idea is well the machine, right, the x86 hardware, that actual CPU is executing ones and zeros. And as much as we humans would love to just use a keyboard with ones and zeros and just bang and pound sequences of ones and zeros into the computer, it's not really the best way to code a program. Even when we're talking about at this very low level here at the assembly language. So the idea is we provide and we're going to look at a slightly higher level language than machine code. So assembly language is basically right above machine code. And so we should be able to see, okay, yes, that the program actually is able to, that there is basically a one-to-one mapping between this assembly language and the actual ones and zeros that get output. So an x86 assembly language program is made up of directives. So remember from our previous study, we've seen that on GNU and Linux, the AS command, the assembler command takes in x86 assembly language and then outputs that binary object, which is that actual machine language. So just like when we program in C and we have directives like the pound symbol that our preprocessor macros for the preprocessor, those actually aren't part of the language, but they're important parts and information essentially to the compiler. So here we're actually talking about assembly language is a specific compiler and the assembler takes in assembly language and outputs machine code. So we can have directives that are commands for the assembler. And in those directives, we specify different sections. So dot data is how we specify variables in x86. Then we have instructions to the actual operations. So they'll look something like this, JMP to some address. So this JMP is an x86 mnemonic and it has a very precise execution semantics. And it also maps to an explicit binary encoding that you can actually look up. So unfortunately, so for any language, right, we have to define the syntax and the semantics for historical reasons that I'm not really going to get into. There's actually two possible types of syntaxes in x86. You might say, well, Adam, how is that possible? How can we have one language with two possible syntaxes? That seems crazy. Why would you want to do that? We don't in our normal high level programming languages, we don't have multiple types of syntaxes for C for instance. And it turns out it does. So in the assembly instructions, as we'll see are very kind of simple. But a lot of what we're going to be doing, right, we've seen the CPU, we've seen we have registers. So a lot of what we want to do is do either computation or move data either from one register to another or from memory to registers or from registers back to memory. So the key difference between the syntaxes is what is the order that that happens in in the actual assembly language instruction like this jump instruction here. So there's two types of syntax or AT&T syntax, which have the mnemonic as we saw here like jump, and then first the source then the destination. So it would be, for instance, move EAX into EBX is how you would read that. And that's used by ObjectDump and the GNU assembler AS. The other style, DOS or Intel syntax, which is used by the Microsoft assembler, NASM and IDA Pro, the mnemonic remains the same, right, which makes sense because we're using mnemonics from the x86 assembly language. But the destination and the source are flipped. So in this, you read move the source into the destination, but you have to know move source into destination here. So it's important, the real important thing from this is to know that there are two syntaxes. So if you're trying to read x86 assembly code, right, assembly language, you actually, in order to understand the semantics of what does this instruction mean, you have to know precisely what syntax you're using. So if you don't know that, you're never going to be able to understand the code. So A, it's important that you know that there are two different types of syntaxes. And in a lot of tools, like for instance in GDB, we can set the syntax specifically to either Intel or AT&T. For this class, we're going to use AT&T syntax from here on out. I hope. So hopefully all the examples, if I like that, if there's any questions about it, you can feel free to either email me or ask in class. So in our data section, we can define data. So just like in a normal programming language, we may want to define constants, right? And in the Intel syntax, hexadecimal numbers start with 0x. And we can define any number, actually a good number of data objects. So we can, then the basic syntax is a label. And this label is actually not specific to the language itself. But it allows us, or it's not specific to x86 itself, the CPU knows nothing about labels or how to handle them. But it allows us in our program to reference this label and know that it's that segment. And the assembler's job is to then link up those references to this actual address. So types can be just as we've seen previously when we were studying the x86 machine, types can be either bytes, words, double words, or quad words. And so for instance, in a dot data segment, you can define something called my variable. And it can be two double words. The first one is 12345678. And the next one is 23456789. We can also define a variable bar and have it be just a word. And so that would be the 16 bits here, we can define strings. So this my string is a string that's three. So it's bytes. So you can see here from the DB, it's a bytes. So there's the bytes f, the whatever x f is an ASCII. If we were in class, I'd ask you to look it up. f00, all in ASCII. So those ASCII values followed by a null terminated zero. So now that we're able to define, so this is how in x86 assembly language, we can define constants and data. We need to know, okay, how do we access memory, right? So before we actually looked at the memory mode of the processor, right? So we looked at the differences between the flat memory model and the segmented memory model. And in x86 to access memory, regardless of kind of the mode of the processor and the mode of the memory accesses, all memory access is going to be done with five things here, the width, the base, the index, the scale and the displacement. So the width is fairly simple. The width is the data size that you're transferring. The base is the starting address of the reference. And so the index, so the index is an offset from the base address. And the scale tells you what the multiplier is of the index. And the displacement gives you a constant offset from the base. And where the width, you can tell the width based on the address suffix of the description. For instance, B will be byte, S will be short, W will be word, L will be long, Q will be quad. So the basic idea is when calculating an address in x86 assembly language, the actual address that you're going to be fetched or that we're either going to store or load data from is going to be the base plus the index times the scale plus some displacement from that. And this is going to be represented into the AT&T syntax for x86 assembly language like this. So whenever we're going to use a memory reference, we're going to see this displacement and then we're going to have the base, the index and the scale. So for an example, we could see an instruction like this. So let's decode and break this instruction down. So here we have a move L and you've got to make sure that that's not a one. So we see this L, we know from this it's a long, we know from our discussion of data sizes that the L is 32 bits. So we're moving 32 bits, we're moving a word 32 bits. So then the next question to ask yourself is okay, then what are the semantics of this part of the command of the assembly language? This is x86 assembly language instruction. So remember with the AT&T syntax that we're talking about, the destination is always the rightmost. So here we're moving whatever this memory address is into edx. So that after this instruction is executed, the register edx holds the value of the word that is at this address. So then how do we calculate that address? Well, we just simply follow this formula. So we take the base is eax, we're going to take eax. So whatever value is currently in eax, we take that value, we add it to ecx times four. And then whatever that is, that's going to give us some value and then we'll subtract hex 20 from there. So okay, let's see if we can try to develop some sort of intuition about how we can think about the base index scale and displacement. So I like to think about these first three, the base index and scale, I like to think about them like an array. So if you think about a C array, a C array is just a contiguous sequence of bytes or some kind of data type. So if we have a byte array, which is a character array, a char array, the address would be that address of our array, so it would be eax. And then the index would be our index into that array. So it would either be zero, one, two, three, four, just like we want to access of what element of that array we want to access. Then the scale gives you the size of the data type of this array. So in the case of a bytes, the size would be one. So we know that the first byte is located at, or the zero-width byte is located at eax. So it'd be eax plus zero times one. And the next byte is going to be eax plus one times one. So it'll be the next byte, eax plus one. And so for something like four, four would mean that the size of the data that's in eax is that eax points to is going to be four bytes long. So it's going to be a long. So this means that ecx is essentially our index into this array. That's in eax. So wherever eax points to, we're going to go down four times ecx, which is going to give us that value. And then this displacement allows us, it actually becomes very important when we're doing local variables as we'll see later. So kind of, you know, and obviously the order of this addition doesn't matter. So I like to think about it as eax minus 20 hex plus ecx times four. We're going to move that, what's in that memory location into edx. So another important thing to note here, right, is when we are addressing memory like this, we're actually doing essentially a dereference, right? So what's in eax is an address, but we're moving the value in that address, well, in that address plus ecx times four minus 20, wherever that address is, we're moving the value in memory into edx. Okay, so some more examples. So the way you can get the most out of this, if you're, well, you have to be watching this video from somewhere else. Otherwise, you're in this hotel room with me, which would be very weird. So for addressing memory, so what would be most helpful is to look at this and kind of pause it and go, okay, what do I think this output of this command does? What semantically does this x86 instruction do? So we'll walk through this one. Okay, it's a long, so we're moving 32 bits along. We're going to move ebp minus 8 into eax, right? So this is copying the contents of the memory pointed by ebp minus 8 into eax. Let's look at something slightly more complicated. So what would this assembly instruction do? So here we're moving, so remember, the first thing the size, the L tells us 32 bits. Destination to source, so source is on the right. So here we are, so here we have an example where we have an index, the index is eax. Sorry, we have a base, the base is the register eax. We don't have an index, we don't have a scale, and we don't have a displacement. So we are copying the contents of the memory pointed by eax into eax, right? So essentially we're dereferencing eax and storing it back into itself. So one of the things you can do is try to convince yourself why this is a memory dereference, so why this is similar to a pointer dereference. Okay, so now let's look at this example. So what is this example doing? Right, so here we're moving contents from memory into a register, and so now here we're moving along once again 32, we're moving a register, the value that's in a register, into memory. So which memory address? We're going to take edx, we're going to move it into edx plus ecx times 2, right? And so whatever's inside that register eax is going to be moved to that memory address. Okay, so one thing we haven't seen before, so in the syntax that we're using for x86 assembly, the AT&T syntax, constants are represented with a dollar sign. So here we're moving the constant 804a0e4 into the register ebx. So this is how we can copy values. So important thing to note, the difference between this and all the other examples, all the other examples had memory access, right, which is essentially doing pointer dereferencing. But here we're just copying this value into ebx. So if we wanted to do something different here, here this would be the way we could actually have a constant memory access memory dereference. So here we are taking the content of the memory at address 804a0e4, taking the value that is at that memory location and moving it into eax. So this is something that's going to be important and is going to definitely help when we're looking at x86 assembly code. So I highly recommend you take the time to walk through these examples to understand exactly what's doing, what's happening. Okay, so instruction classes. So the instructions, the types of x86 assembly instructions fall, there are all kinds of different classes. As we've seen, some allow us to transfer data, right? So if you think about, these are actually some of the fundamental things that we want processors and CPUs to be able to do. So we want to be able to move data from memory into a register. We may want to exchange data between registers. We may want to, we'll see, pushing and popping. So these actually implicitly use the stack pointer. So these push, push will push a value from a register on or memory, I believe, on to the stack and pop will take that first value off the stack and put it into a register. We can also, so these are kind of the getting data into our program. We can also perform computation on that data. So we have all kinds of binary arithmetic where we can add things, subtract things, multiply, divide, increment things, decrement things. Basically all the building blocks you need to write and do any kind of complicated logic. You know, important things to think about and to note, what happens when we have an overflow? So an overflow would be when we perform one of these arithmetic operations, addition, multiplication, and we have a value that's more than 32 bits, because there's a hard limit on the size of numbers we can represent with 32 bits. So if we have a number that's greater than that, what happens? So I'm not going to go into the details of that here. We also have some logical comparison operators. So we have ands, ors, x, ors, nots. So you can build any kind of complicated logical expressions that you want. And then finally, with those building blocks, we want to be able to change the control flow of the program depending on the conditions of these logical checks. So we need some kind of control structures. So we have ways to jump to different parts of the code. We have x86 instructions to call code. So this helps us implement functions. We can return from calls. We can do interrupts. So an interrupt is when an interrupt occurs, it basically forces the processor to immediately jump to an interrupt handler. So some other piece of code will handle that interrupt. This is specifically how the user space application can talk to the kernel by issuing interrupts. iRet is an instruction to return from the interrupt. And so in order to do interesting control flow, we want to actually jump to and execute certain parts of code only conditionally. So the cmp x86 instruction allows us to do this. So if we compare source and destination, it subtracts the source from the destination and doesn't save the result anywhere. And this is actually what this cmp instruction is, sets all the bits of eflag, the eflag registers. And then we have different types of jump instruction that will jump if certain eflag bits are set. So jne, which is jump if not equal, will jump only if the zero flag is zero, jump if equal, the opposite of that will jump to the code if the zero flag is one, jump greater than or equal. It checks this. Oh, je, jump if I believe an overflow occurred. No, maybe that's wrong. I have to look up exactly what these ones were. But the idea is for all these ebit flags, we can jump depending on the conditions of there so that the programmer has control over what happens in these circumstances. So this control, if the destination can be a constant, so it can be, hey, jump to this memory location if this thing happens, or it can be indirect. So indirect would mean that, hey, jump to the address stored in register eax. Right, so this is something that can actually change at runtime where you actually jump. And there's various other instructions, how to deal with input output devices, other kinds of instructions that are going to be interesting is a no op. So nop stands for no operation, so basically telling the CPU to do nothing. So maybe it's interesting to think about, well, why would you include an instruction that specifically does nothing? So if you remember back to your computer architecture days, so CPUs have a pipeline of instructions and they're executing actually multiple instructions concurrently in this pipeline so that there's a lot of instructions that are going on through that pipeline. Depending on the actual CPU, you may need to specify no ops in order to handle this, the concurrency and the pipelining here. So no op instructions allow you to do that. That isn't to say that this is the only type of operation that is a no op, you could have an instruction that, let's say, moves a register to itself. So move eax into eax. You could do that instruction, it doesn't change anything. Okay, so a key part of x86 programs is how do we actually get something to happen? So you can go through all these instructions, you can write these system, you can write these x86 instructions, but how do we actually get something to appear on the screen? And the way this happens is through system calls. So system calls, the whole idea of the system call is this is what defines the boundary between the application and the operating system. So the operating system defines a number of system calls and the applications invoke those system calls to call parts of the kernel. So this is part of the abstraction that the kernel provides. So instead of every application having to understand how to deal with ext2 file systems, the operating system has a system call that says open a file and write to a file. And in this way, applications don't have to have that functionality of how to deal with all types of different file systems. The operating system needs to know how to do it and the operating system provides this standard interface that all applications can call and invoke. So this system call interface explicitly defines here this interaction between these these two processes. So usually, you know, when you're code in C, even though we talked about, okay, you code a program in C, the C program gets compiled by GCC into assembly, which gets compiled by AS into a binary file and that gets linked with LD into an actual ELF executable. So and you say, well, Adam, I can open files and I can print to files and write to files. And I use stdio.h to do that, right? It handles that. So I can use fprintf to print to files. I can use printf to write to the console. So usually, these system calls are invoked through libraries. So actually under the hood, if you dig into libc, the printf function does nothing but calling the write. So Linux and x86 has a write system call to write out a string to the console. And so all printf is doing is parsing the arguments that you're passing into printf and calling that system call write number of times. So on Linux x86, the way an application calls into the kernel is through an interrupt. So the specific interrupt it says is int 80. So int 80 tells the interrupt handler, hey, the program that called this is trying to call a system call into the kernel. And so when it does this, right, so essentially, if you think about it, this is really kind of like a function call. We're trying to call some function inside the kernel to do something for us. And so when we see this, but to do that, we have to have a well defined interface so that we're not in, if you think about the process space, we're our own process executing our own thing. We don't just jump into kernel memory and start executing kernel code. There's a lot of protection mechanisms that need to go on. So there's a standard that defines on Linux, how do I tell the OS exactly what system call I want. So the way you do this is EAX contains the system call number, and then EBX will contain the first argument, ECX will contain the second argument, EDX will contain the third argument. And I believe any other arguments are put on the stack. And so we can look at a hello world assembly file. So we can say that we have some data, and we'll give it a label called hw for hello world. And our data is a string. And so we have the string hello world slash n, then dot text specifies, okay, this is a compiler directive that says, okay, the next thing is code dot global main. So we're going to define a label called main. So the colon here means that this is a label. And dot global says this is actually for the linker. So this says, hey, when you look at this, I'm defining an exportable label called main so that other people can link to and call this symbol main. And this is important because this is how the loader knows which method we want to execute first, right, where the entry point to our function is. And so here we know, so this directive, this dot global tells the link linker, hey, I want to execute main as my entry point. So the simple hello world is first going to move the constant four into EAX. It's going to move one into EBX. And then it's going to move HW. So HW is this label here. So this is a placeholder, right, this HW is a placeholder. And so we're going to move, which will be at link time, this will be the address of wherever this string is located in memory. So we're going to move that string address into ECX. Then we're going to move 12 into EDX. Finally, we're going to call into AD, hex AD. So what's going to happen? Okay, so we do this. Well, we know from what we just talked about that the system call number is going to be put into EAX. So EAX is going to be four. So four is actually the read system call. So now if I can, all right, if I can go into my terminal, I can say man, let's, I think it's section three. No, I think it's section five, six. It's not a bash built in, two. Okay, perfect. Okay, so in UN universal standard.h, this defines all of the system call parameters here. So this is actually the function that I'm calling. So if we look in here, let's do that. Okay, I didn't plan on doing this. So we'll, maybe I completely mess everything up. User lib, user lib, find user lib. That did not work. Maybe I don't have the header files installed. What happens when you do a live demo that you didn't plan on doing beforehand? So we'll see. Ah, user include. That's right. Okay. And we can see it's not only in user include. So we have user include UNi, std.h, but we also have it in the source. It's getting into now Android stuff, which we don't want. We can see here that it is also in the kernel source code. So in this distro that I'm using, it includes the kernel source code. So let's look at this file. And so we can see this is a .h file. It's got a lot of defines here. Okay, and we can see that it defines this read command here, this read function. And I thought it had the list of all of the, maybe it's in sys, assemb, maybe in ASM, assembly. Ah, there we go. Okay. So we can see that in this one .h. So these pound of fines says if it's a 32 bit architecture include UNi, std, underscore 32.h. So now I can look at 32.h. Bingo. Here we go. So this file contains all the system call numbers. So we can see that, ah, very good. I've been talking about the wrong thing. It's very good that I did this. I'm actually not trying to read. I'm trying to write. So I can see in here that by moving four into EAX, I'm saying I want to call system call four. So this shows you all of the system calls that the Linux library is actually exporting to you. There's exit, fork, read, write, open, close, wait, PID, create, link, unlink, time. You may have actually used some of these functions and maybe not realize that you weren't actually using a libc function. You were actually using a kernel system call. So the Linux kernel was actually doing this on your behalf. And we can see it goes on for a long time. I wonder where the bottom is. Let's see. All the way at 348, process, vm, write, and v. Okay. So now that we did all this, we know that we're actually not calling read. We're calling write. So we see, okay, write takes in a file descriptor, a pointer, a void star. So void star is a pointer. So the address of a buffer and some count. So what does it do? It says it writes up to count bytes from the buffer pointed to by buff to the file referred to by the file descriptor FD. The number of bytes written may be less than count if it's writing to a physical byte. So it's writing the number of bytes from the buffer to the file descriptor. So then let's sync this up to what we know about system calls from this code here. So we know that four into EAX defines the write call. So write means, okay, perfect. I know, I know that we're calling the system call that we're trying to call is the function write. Now, the first, so what we know about system calls is that the first parameter of the system call is going to be stored into EBX. So if I look here, I see that one is going to be stored into EBX. So one in write, so one is going to be then the file descriptor. And so the other convention about UNIX is, let's see, standard out. Yeah, okay, perfect. So important thing about UNIX is that on program startup, the integer file descriptors associated with the streams standard in standard out and standard error are zero, one and two. So what this means is every process that's executed on UNIX, file descriptor zero, the integer zero maps to the stream standard in. So every time your program is reading input from standard in with either gets or scan F or if you're using one of the C plus plus libraries, this is reading from the stream standard in. And so here with writing to file descriptor one, we're actually writing to standard out. And if we wanted to print out an error message, we would write out to two, which is standard error. Okay. So now if we go back to the write call, now we know, okay, we're writing to standard out. And what are we writing the standard out? Well, the next argument here is the buffer. So if we look at here, we're moving hw, which is this address of the string into ECX. So that's what we're printing out. So ECX is going to contain the address of the string hello world. And then we're moving 12 into edx. So 12 is the count. So this is the number of bytes that's going to be output, a number of characters. So if we look here, we see 123456 for the space seven, eight, nine, 10, 11, 12. So this should print out this whole thing. And then we call in 80, which means we invoke that call. So let's maybe see if we can write this. Yeah, let's try to write this. Okay. Test.s. So we're going to give it the .s file name so that GCC knows that this is a, oh, and I already have a test.s in there. 545.c. Right. So this is not something I was planning on doing, but I think it'll be fun so that you can see. And then we can actually talk about some of the things here. All right. So we're moving four into eax. This tells us that we want to do the right system call. We're moving one into ebx to say we want to write two standard out. We're moving the address of wherever the linker decides to put hw to the hello world string into ecx. We're then going to move the constant value 12 into edx. Then we're going to call int 80. And then because we're good people, we are going to return successfully from this program. So if I write this out, assuming I've done everything correctly, this should work. If it doesn't, well, it'll be fun. Oh, I would be because I named it hello world.c, which is not a c file. Hello world dot s. So I'm going to compile it. Remember, I'm going to use the m32 flag to say I'm compiling a 32 bit program.  It compiles. If I execute it, bang. So everything works correctly. We can see that it actually is outputting hello world. And I think I believe I give this the dash s flag. It will output. What does it actually do? Okay, well, I already have the assembly file. Oh, this is what I wanted to do. Okay, so I'm going to compile this as 32 bit. We didn't show exactly how to do this, but we will in a bit. So I'm going to look at the, what I want to look at here is I want to look at this assembly code that the, that AS actually generated for this hello world. So if I look at this, at this, I have to do this on the object file, object dump is going to try to turn the machine language, the zeros and ones of this a dot out file, and it's going to try to output that to me and show it to me. So I want to run this through the less command. And I want to see the main function. And I know that main is that function that I actually wrote. So we can look here and we can compare it one to one. So you can see, okay, move four, move four into EAX, move one into EBX, move this 804960C to ECX, move hex C into EDX. So C is 12, then call in 80, then move zero into there. So what is this address? Let's look up this address. So we'll search for 960C. So what this output is, the way to interpret this output is object dump has read the elf file format here. And it knows the mapping that the elf file format says the mapping between that file and where those things should go in memory. So in one of those elf headers, it says, hey, at 0804960C, there's a label called hardware. Now, this on the right here is object dump trying to interpret these bytes as if they were x86 instructions. So this is going to be garbage. And as we can see, it is in fact garbage. But in this middle column here, we can see the bytes. So we have the byte 40. So at this memory address, we have byte 48656C6C6F2576F7260C640A00. And if we look this up in our ASCII table, so if I look up what's hex, I want to know what is ASCII in hex 48. So hex 48 is right here. And it is the H character, which matches up to the H here. And we look at 65. I bet you that's going to be E. Actually, I know, so sad I have not memorized the ASCII table not quite yet. If I look at E, E is 65. So I know that this string is this at memory location 0804960C is the string hello world. And remember, the string is a sequence of bytes followed by 0. And so the linker actually took this program and said, OK, I'm going to put this string at this memory location. It just decided. And then so here in this instruction, as we saw in Main, this instruction here, so then it changed this instruction and actually put in this exact address in here. Cool. OK. So now we've actually looked at this. I actually encourage you to do the same thing. It'll help you become more familiar with assembly language and the compilation process. And I think it'll be hopefully an interesting and educational experience. OK. Let's go. We've already done that. So there's a couple other segments of X80s of ELF files that are important. So the PLT and the global offset table, the GOT. So this is actually getting into more details about how this dynamic linking is done. So we've actually just seen a little small example about how linking is done on when you have static constant values when you're doing statically linking. So we use the name HW, but that name HW needed to be matched up with an actual address. So the linker is the one that did that. So when we're doing static linking, it's very easy. The linker does all this, changes all the labels to addresses, and outputs everything. But the question is, how does this happen at runtime when we want to do dynamic linking? So we essentially have to do this mapping. So the idea is when your program calls a shared library function, the address of what's called is stored in the Procedure Linking table. And the address is going to contain an indirect jump to an address that's in the global offset table. So the idea is basically the way this works is the first time you call a function like printf, the global offset table. So the global offset table is a table that at runtime tells you the location of all of these dynamically imported libraries. So the first time you call a function that is dynamically imported, in the global offset table is an address that jumps back to the PLT because there's no way to you don't actually have that function stored in your program yet. So basically the linker actually will do its magic at runtime, find the proper version of the .so file, load it up, read the memory, get the function, and then it will change the GOT entry so that the next time that printf function is called it's going to execute it directly. And we'll see this is a little future note that the PLT is actually read only but the global offset table is not because clearly the PLT has to overwrite the global offset table. So great. So we will end this here, this lecture here. So I hope this has given you a good overview of x86 assembly language. I encourage you to play around with this, do these types of things on your own, and when we get back we're going to go into how processes are actually loaded and executed and then we'll actually start really getting into some attacks. So I look forward to seeing you all on Friday.