We may earn an affiliate commission when you visit our partners.
xor pd

Learn Assembly Language

The x86 Adventures series teaches you your computer's language - x86 Assembly language, from scratch. No prior knowledge is assumed.

[Complete Course]

This is the full collection of x86 Assembly Adventures. It covers everything from the real basics to being an independent (and tough) x86 Assembly programmer.

Main topics covered:

Read more

Learn Assembly Language

The x86 Adventures series teaches you your computer's language - x86 Assembly language, from scratch. No prior knowledge is assumed.

[Complete Course]

This is the full collection of x86 Assembly Adventures. It covers everything from the real basics to being an independent (and tough) x86 Assembly programmer.

Main topics covered:

  • The Binary System

  • The x86 Architecture

  • Intro to Flat Assembler

  • Branching

  • Signed and Bitwise Operations

  • Memory

  • Strings

  • Subroutines and the Stack

  • Reading the Manuals

  • Debugging

  • Dealing with Windows API

Why learn x86 Assembly Language?

  • You are the kind of person who really likes to know how things work. In this course you are going to get solid understanding on how computer programs work from the inside.

  • Become a better programmer - Knowing how things work down there will help you take better decisions, even as a high level programmer. If you were always wondering what is the stack, or what are those pointers everyone talks about, you came to the right place.

  • Write faster code - When you really want to get the most of your processor, writing in raw Assembly is needed. We are not going to talk about optimizations in this course, however you will get a solid foundations so that you can continue exploring on your own.

  • You want to become a reverse engineer or a security researcher, read the code of viruses or look for software vulnerabilities. As most of the time the original source code will not be available to you, solid understanding of x86 Assembly Language is mandatory.

Course structure

The course is made of video lectures. A lecture could be from a presentation, or a real world example, showing me doing stuff at the computer. Almost every video lecture is accompanied by some kind of exercise. The exercises are open source, and you can get them from github.

It is crucial that you complete the exercises. You will learn a lot from the lectures, but it is pretty much a waste of your time and money if you don't do the exercises. (Or at least verify that you know how to do them, if you are more experienced).

Course tech stack

No prior knowledge is assumed for this course, but I do assume some things regarding your system, so make sure that everything here describes you:

  • You are using a Windows operation system. (The course videos use Windows 7). It is recommended to use at least Windows XP. (This means it will work perfectly on Windows 7 and Windows 10).

  • You have an x86 processor. We study 32 bit x86, but this course will also work on 64 bit processors.

For the tech savvy, some more details about the tools we are going to use in this course:

  • Assembly flavor: x86 32 bits protected mode.

  • Assembler: The Flat Assembler (FASM)

  • Debugger: WinDbg.

Using Linux? Most of the exercises were ported to Linux, however the videos show me using windows 7. Please contact me if you are not sure.

Enroll now

What's inside

Learning objectives

  • Learn to code on the x86 architecture using assembly language
  • Gain solid understanding about low level concepts.
  • Understand how your computer works
  • Become a tough person

Syllabus

Intro

General information about the course: List of main subjects to be covered during this course, some technical details and some requirements for the course.

Read more
Where are the exercises?

Explaining the file explorer - The program we use to view files on our computer. We also discuss Total Commander, which I am going to use during this course.

Explaining the Hex Editor - A program that allows us to view the internal structures of files inside our computer. Specifically we discuss the HxD Hex Editor.

We discuss Text Editors - programs that are used to view and edit text files inside our computer. We introduce notepad, notepad++, and a bit of vim.

The Binary numeric system

We discuss the idea of numeric bases, and specifically we take a look at base 10 and base 2. Finally we have some examples of addition and subtraction in base 2.

We introduce three ways to convert numbers between different numeric representations: Direct evaluation, Finding largest power and Remainder evaluation.

We discuss how to decide which conversion method to use in different cases, and also show a few examples of converting numbers between different bases.

We discuss the Hexadecimal base (Base 16), and show its special relation to base 2.

We answer the question: Why is every hex digit is represented by exactly 4 binary digits?

We discuss the subtraction operation, and also negative numbers, in the base 10 representation. We study how to invoke subtraction using only the addition operation.

We introduce the two's complement representation, which allows us to deal with signed numbers in base 2, just like we did previously in base 10.

We look at examples of signed addition, we deal with some exceptions regarding
the two's complement representation, then we view a graphical representation of
the positive and negative numbers in the two's complement, and finally we
discuss some philosophy of representation.

x86 Architecture

Basic history of the x86 architecture: The first processors in the family, the idea of backwards compatibility in the x86 architecture, and the different modes inside the x86 processors.

We explain how programs are stored in memory, and how they are executed by the processor. Next we study about the x86 32-bit registers.

We learn about the general structure of x86 instructions, and we discuss the MOV instruction.

We introduce the ADD and SUB instructions.

We introduce the INC, DEC and MUL instructions.

We introduce the DIV instruction.

We show examples for exceptions generated by using the DIV instruction.

We look at some examples of using the DIV instruction (With numeric examples). Finally we summarize the Basic Arithmetic series of lessons.

Introduction to FASM

Introducing FASM - The Flat Assembler.

We discuss a few different common assemblers, and finally we describe FASM, and a few different reasons to use FASM. We end with a short description of how to install FASM. We will expand on this in the next lessons.

Fasm installation. We take a look at Fasm's website, and explain how to download and install Fasm.

We assemble our first program - bare.asm, and view the generated file in a hex editor.

We take a look at the program console.asm, which is our first console program. We discuss the source code of console.asm

We try to assemble the console.asm program, and we have to fix the INCLUDE environment variable to make that happen. Finally we manage to assemble and run the program. We then analyze the output file with a hex editor.

We introduce first_program.asm. This is our first program that actually has input and output. We take a look at the source code, and compare it to console.asm, the previous program. Later we try to assemble the program. For that task, we have to update the INCLUDE environment variable. Finally we run the program, and analyze the output of the program.

We create our own program, based on first_program.asm. Our program will read two numbers from the user, add those two numbers, and then print the result back to the console.

We introduce different examples of assembly time errors, and how to deal with them.
We begin with the Write Failed Error.

We introduce more examples of assembly time errors and how to deal with them:
File not found error, Undefined Symbol Error, Illegal Instruction Error, Sizes
don't match error, Another Undefined symbol error and finally Invalid Operand
error.

Branching

We introduce the idea of branching: Having our program run in a nonlinear
fashion. We then discuss the EIP register.

We introduce the JMP instruction, we discuss labels, and we view a simple
example of using the JMP instruction.

We take a look at two examples using the JMP instruction: An infinite loop, and an example of skipping instructions using the JMP instruction.

We introduce the Flags register, and discuss the Zero flag.

We discuss the Sign flag and Carry flag. Then we look at a few examples about the Carry Flag.

We discuss the Overflow flag and view different examples regarding the Overflow flag.

We compare the behavior of the Overflow and Carry flags. We also view different
ways of using the Overflow flag and Carry flag for the Signed and Unsigned
numbers.

We describe the idea of conditional branching, and see some examples of using the JZ and JNZ conditional branching instructions. We then briefly mention some other conditional branching instructions.

We introduce the CMP instruction, and the idea of comparing numbers. Then we discuss unsigned and signed comparison, and we introduce specialized instructions for unsigned and signed comparisons.

We describe signed comparison in a more detailed fashion, and add some note about writing readable code with specialized jump instructions.

We introduce the idea of Structured Branching and its advantages for writing good code. We then discuss the pattern of conditional execution.

We discuss the pattern of loops, and breaking from loops.

We introduce some branching rules of thumb. Then we show an example of simplifying a spaghetti code using the idea of Structured Branching.

Signed Operations

We learn about the NEG instruction, and we discuss the concept of sign
extension. We introduce the instructions MOVZX and MOVSX.

We discuss the differences between the MOVZX and MOVSX instructions. Then we
study the instructions CBW, CWDE, CWD, CDQ.

We introduce the IMUL and IDIV instructions, the sign aware versions of the MUL and DIV instructions. We explain how they work, and finally show an example of using those instructions.

Bitwise Operations

We introduce the idea of basic statements, and the basic operators NOT, AND and OR.

We discuss the truth tables and Venn diagrams of the basic operators (NOT, AND,
OR). Then we view a few examples involving the basic operators.

Basic properties of the NOT, AND and OR operators: Double negation, Commutative laws, Associative laws, Distributive laws. Finally we show an example of using Venn diagram to verify the truthfulness of an equation.

We introduce De Morgan's laws, followed by a few examples of simplifying statements. Then we discuss the XOR operator. Finally further research subjects are mentioned.

We introduce the NOT, AND, OR and XOR instructions. Then we discuss Bit Shifting using the SHL and SHR instructions.

We discuss arithmetic shifting (Shifting that understands the sign) using the SAL and SAR instructions. Finally we introduce the ROL and ROR instructions, used for bit rotation.

We study some basic bit manipulation techniques: Extracting one specific bit from a number, Counting the number of 1-s in a binary number, Calculating modulo powers of two using bit operations and finally squeezing a few small numbers into the same container.

Memory

We first discuss the reasons for which we need more data in our programs. Next
we describe the basic model of the computer memory, and discuss memory devices
which reside outside the processor.

We discuss memory abstraction mechanisms supported by the x86 processor. We
mention Segmentation and Paging, and show a few illustrations of the Paging
mechanism.

We introduce the program reverse.asm, which uses the memory (The RAM) to reverse
a list of numbers. We run the program and analyze the source code.

We analyze the internal structure of the output executable file of reverse.asm using a hex editor.
Next we continue with reverse_constant.asm, which improves reverse.asm by using a constant.

We introduce the get_addr.asm program, which demonstrate the meaning of labels, and possible syntax when using labels.

The program corrupt.asm demonstrates what happens when we try to access memory that we do not own. fix_corrupt.asm demonstrates how to fix corrupt.asm, and finally fix_corrupt_small.asm uses the bss section to get a much more efficient solution.

We discuss different ways of defining data, and inspect the output for each data definition. We learn about bytes, words, dwords, arrays and a bit more complex data definitions.

We introduce the PE sections, and show an example of a program that contains different sections: text, data, bss and idata. Finally we inspect the resulting executable file with a hex editor.

We show how to access memory using assembly instructions. In this lecture we study how to count addresses properly, how to store a dword in memory (Endianity), advanced addressing with the brackets syntax, and some limitations when accessing memory in the x86 architecture.

We introduce the LEA instruction. We discuss the syntax of this instruction, and then show a few examples of using the LEA instruction.

We explain the need for a way to organize our data, and propose the structure syntax as a solution. We then discuss different ways of defining and declaring structures.

We show different examples of using structures, and then we discuss the possibility of nesting structures.

We discuss Unions, and we view an example of using unions (Unions IPV4 example).

We take a look at a few examples of memory constructs: Array of structures and
Two dimensional table. We put emphasis on the techniques of storing those
constructs inside our program's linear memory.

We show an example of storing a multiplication table into a two dimensional
array. Then we discuss the possibility of storing higher dimensional arrays
inside the program's memory.

We discuss the memory construct of Binary Tree, and show an example of representing a Binary Tree in memory.

We describe a few rules of thumb regarding address arithmetic. Those rules help distinguish between addresses and offsets.

Strings

We introduce the ASCII standard for encoding text as numbers inside the computer. We also mention the Unicode standard.

We introduce the Character Map windows program, which is a tool for viewing different characters and their corresponding ASCII or Unicode codes.

In this video we explain how to represent text strings inside our own assembly programs. We also introduce two schools of strings: Length prefix and Null terminated strings.

We show an example of using Unicode characters inside a Fasm assembly program. In this example we want to store two Chinese characters in memory. Eventually we assemble the program and view the output file inside a hex editor.

We introduce the STOS instruction, and show a simple example of using this
instruction. Then we discuss the direction flag and its significance.

We introduce the instructions LODS, MOVS, and we show simple usage examples for
both of those instructions.

We introduce the REP prefix, and use it together with STOSB to clear an array. Next we introduce the SCAS instruction. Finally we introduce the REPNZ prefix, and use it together with the SCAS instruction to search for the NULL terminator of a string.

We discuss the REPZ and the REPNZ prefixes. Then we introduce the CMPS instruction, and show an example of using CMPS with the REPZ prefix to check the equality of two memory buffers.

Subroutines and The Stack

Subroutines are independent pieces of code. We explain the need for subroutines, and next we try to create our own subroutines using a simple JMP instruction. This first attempt is not so successful, but it prepares us for a more advanced idea of implementing subroutines, which we are going to see in the next lessons.

We study the Stack data structure. Then we study the x86 stack implementation and instructions (PUSH and POP). Eventually we see some simple examples of using the stack.

We show an example of using the CALL and RET instruction to implement a
subroutine. Then we study CALL and RET in detail.

We see a few examples of using the CALL and RET instructions. Then we explain
the Stack's meaning with respect to function calls.

We explore different methods of communicating with subroutines: Registers, Global data and the Stack.

We discuss the idea of calling conventions. Then we introduce the CDECL and
STDCALL calling conventions, and compare them.

We introduce the EBP register, and we explain how to use it to hold the stack frame in our functions. Next we discuss local variables, and how to use the stack to store local variables for the current function.

We introduce the idea of The Call Stack, and next we study the ENTER and LEAVE instructions, which are shortcuts for creating and destroying a function's stack frame.

Manuals

We show how to obtain the Intel and AMD instruction set manuals.

We take a look at Intel's Instruction Set manual, and explain how to use it.

We learn how to read information about specific instructions inside the Intel's
Instruction set manual. Specifically we study the ADD instruction, and the ADC
instruction.

Save this course

Save Assembly Language Adventures: Complete Course to your list so you can find it easily later:
Save

Activities

Be better prepared before your course. Deepen your understanding during and after it. Supplement your coursework and achieve mastery of the topics covered in Assembly Language Adventures: Complete Course with these activities:
Review Binary Number System Fundamentals
Reinforce your understanding of binary number systems, which is crucial for grasping how assembly language interacts with hardware.
Browse courses on Binary System
Show steps
  • Review the concepts of bits, bytes, and number representation.
  • Practice converting between binary, decimal, and hexadecimal.
  • Solve practice problems involving binary addition and subtraction.
Read 'Assembly Language for x86 Processors'
Deepen your understanding of x86 assembly language with a comprehensive textbook that covers a wide range of topics.
Show steps
  • Obtain a copy of 'Assembly Language for x86 Processors'.
  • Read the chapters that align with the topics covered in the course.
  • Work through the examples and exercises provided in the book.
Read 'Programming from the Ground Up'
Supplement the course material with a book that provides a different perspective on assembly language programming.
Show steps
  • Obtain a copy of 'Programming from the Ground Up'.
  • Read the chapters covering basic assembly concepts and program structure.
  • Try to compile and run the examples provided in the book.
Four other activities
Expand to see all activities and additional details
Show all seven activities
Create a Cheat Sheet for x86 Assembly Instructions
Consolidate your knowledge of x86 assembly instructions by creating a cheat sheet that summarizes their syntax, purpose, and usage.
Show steps
  • Review the x86 assembly instructions covered in the course.
  • Organize the instructions into categories based on their functionality.
  • Create a cheat sheet that includes the instruction syntax, a brief description of its purpose, and an example of its usage.
  • Share your cheat sheet with other students and solicit feedback.
Assembly Language Coding Challenges
Sharpen your assembly language skills by tackling coding challenges that require you to implement specific algorithms or solve problems using assembly.
Show steps
  • Find online resources that offer assembly language coding challenges.
  • Choose a challenge and attempt to implement a solution in assembly.
  • Test your solution thoroughly and debug any errors.
  • Compare your solution with others and learn from their approaches.
Develop a Simple Calculator in Assembly
Apply your assembly language skills by developing a simple calculator that can perform basic arithmetic operations.
Show steps
  • Design the calculator's user interface and functionality.
  • Implement the arithmetic operations using x86 assembly instructions.
  • Test the calculator thoroughly and debug any errors.
  • Add features such as memory storage and recall.
Create a Personal Assembly Language Reference
Improve retention by compiling a personalized reference guide containing notes, code snippets, and solutions to exercises from the course.
Show steps
  • Review your notes, assignments, and exercises from the course.
  • Organize the material into a logical structure that is easy to navigate.
  • Add your own explanations, examples, and code snippets to clarify concepts.
  • Keep your reference guide up-to-date as you continue to learn assembly language.

Career center

Learners who complete Assembly Language Adventures: Complete Course will develop knowledge and skills that may be useful to these careers:
Reverse Engineer
A reverse engineer analyzes software to understand its functionality, often without access to the original source code. This course helps build a foundation in x86 Assembly language, crucial for deciphering compiled code. The course covers the x86 architecture, which is the heart of reverse engineering, and topics such as memory management. By disassembling and analyzing assembly code, a reverse engineer identifies vulnerabilities and hidden features. The course's focus on debugging and working with the Windows API makes it valuable for a reverse engineer dealing with Windows-based software. This course teaches the foundations of assembly language and computer architecture, exactly what a reverse engineer needs.
Security Researcher
Security researchers investigate software and systems to identify vulnerabilities and develop ways to protect against attacks. This course is directly applicable to a security researcher, as it provides the low-level knowledge needed to understand how software operates and where weaknesses might exist. A security researcher benefits from the course in areas like understanding the x86 architecture and debugging. The course covers debugging as well as reverse engineering, which are key skills needed to analyze software for potential security flaws. The course provides a basis for understanding reverse engineering, making it helpful for uncovering software vulnerabilities.
Exploit Developer
An exploit developer creates code that takes advantage of vulnerabilities in software or systems. This course provides an advantage to an exploit developer, as it offers a deep dive into x86 Assembly language, which is essential for crafting effective exploits. Exploit development often requires understanding the inner workings of software at a low level, and this course provides that knowledge. The course emphasizes areas such as reverse engineering and memory manipulation, which are critical skills for identifying and exploiting vulnerabilities. With the course, an aspiring exploit developer gains the knowledge to write and analyze shellcode.
Malware Analyst
Malware analysts dissect malicious software to understand how it works, what damage it can cause, and how to detect and remove it. This course can be very helpful to a malware analyst, as it offers grounding in x86 Assembly language, which is often used to write and obfuscate malware code. The course helps a malware analyst understand the inner workings of malicious software, and its focus on debugging is essential for reverse engineering. The course provides a base to read the code of viruses, arming a malware analyst with skills to defend against them. Learning assembly language is a must for aspiring malware analysts.
Operating System Developer
Operating system developers create and maintain the software that manages computer hardware and resources. This course may prove beneficial for an operating system developer, as it provides a low-level understanding of how the x86 architecture works. Operating systems often interact directly with hardware, requiring knowledge of assembly language. The course covers essential topics such as memory management and the x86 architecture. Studying this course will improve the skills of future operating system developers, assisting them in building efficient and reliable systems.
Firmware Engineer
Firmware engineers develop the low-level software that controls hardware devices. Firmware engineers often need to write code in assembly language, especially when working with embedded systems or optimizing performance. This course may benefit firmware engineers, as it teaches the x86 Assembly language from scratch. The course covers topics such as the x86 architecture, memory management, and debugging. This comprehensive course on assembly language is a great way for firmware engineers to improve their skill set.
Compiler Developer
Compiler developers create the software that translates high-level programming languages into machine code. This course can be useful for a compiler developer, as it provides a deep understanding of x86 Assembly language, which is often the target language for compilers. The course helps compiler developers understand how high-level code is translated into low-level instructions. The course covers significant areas such as the x86 architecture and memory management. For a compiler developer, this course is a great step to improving their understanding of assembly language.
Game Engine Developer
A game engine developer creates the underlying software framework that powers video games. This course may be helpful for a game engine developer, as it provides insights into low-level programming and optimization. While game engines are often written in high-level languages, understanding assembly language can help optimize performance-critical sections of code. The course emphasizes memory, which might be valuable to a game engine developer. With this course, aspiring game engine developers will have a better understanding of the x86 architecture.
Embedded Systems Engineer
Embedded systems engineers design and develop software for devices with dedicated functions, such as appliances, vehicles, and medical equipment. This course may prove useful to embedded systems engineers, as it gives you a low-level understanding of how computer hardware works. In embedded systems, assembly language is often used to interact directly with hardware components and optimize performance. With topics such as memory management covered, embedded systems engineers may find this course to be valuable.
Software Engineer
Software engineers design, develop, and test software applications. This course may be helpful for software engineers, as it provides a deeper understanding of how software works at a low level. While most software development is done in high-level languages, understanding assembly language can help debug complex problems and optimize performance. The course's coverage of debugging and memory management may make it a worthwhile pursuit for software engineers, as it provides an insight into the x86 architecture.
Technical Support Engineer
A technical support engineer provides assistance to customers experiencing technical issues with software or hardware. This course may be useful for a technical support engineer, as it provides a deeper understanding of how computer systems work at a fundamental level. While not directly applicable to day-to-day tasks, knowledge of assembly language and computer architecture can help troubleshoot complex problems and understand system behavior. The course offers an understanding of the x86 architecture as well as debugging. With this course, technical support engineers will be better suited to help debug issues.
Quality Assurance Analyst
Quality assurance analysts test software to identify defects and ensure it meets quality standards. This course may be useful for a quality assurance analyst, as it provides a deeper understanding of how software works at a low level. While not directly applicable to most testing tasks, knowledge of assembly language can help understand the root cause of complex bugs and system behavior. The course's coverage of debugging may aid quality assurance analysts in their troubleshooting tasks.
Data Scientist
Data scientists analyze and interpret complex data to identify trends and insights. This course may be useful for a data scientist as it provides a foundational understanding of how computers process information at a low level. This course will help learners understand the basics of machine language, which may further their understanding of machine learning. This may allow them to have a more refined approach to managing and structuring data. With the ability to improve processing performance, data scientists may find this course useful.
Web Developer
Web developers create and maintain websites and web applications. This course may prove useful for a web developer, as it teaches a low-level language. While most web development is done in high-level languages, understanding assembly language can help optimize server-side code and understand system behavior. The coverage of the x86 architecture may be a useful supplement to web developers. With the foundations offered in this course, web developers may have a stronger basis for their work.
Network Engineer
Network engineers design, implement, and manage computer networks. This course may provide some benefit to network engineers, as it provides a deeper understanding of how computer systems operate at a hardware level. While networking primarily involves high-level protocols and configurations, understanding assembly language may help troubleshoot low-level network issues and optimize network performance. The course covers many topics, such as dealing with the Windows API. This course may prove useful as supplemental knowledge for network engineers.

Reading list

We've selected two books that we think will supplement your learning. Use these to develop background knowledge, enrich your coursework, and gain a deeper understanding of the topics covered in Assembly Language Adventures: Complete Course.
Provides a solid introduction to assembly language programming, focusing on the Linux operating system. It covers fundamental concepts and guides you through writing complete programs. It's particularly helpful for understanding how assembly interacts with the operating system and hardware. While the course focuses on Windows, the core assembly concepts are transferable, and this book offers a valuable alternative perspective.
Comprehensive guide to assembly language programming for x86 processors. It covers a wide range of topics, including assembly language syntax, data representation, memory management, and input/output operations. It is commonly used as a textbook in academic institutions and provides a solid foundation for understanding assembly language programming. This book adds more depth to the course.

Share

Help others find this course page by sharing it with your friends and followers:

Similar courses

Similar courses are unavailable at this time. Please try again later.
Our mission

OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.

Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.

Find this site helpful? Tell a friend about us.

Affiliate disclosure

We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.

Your purchases help us maintain our catalog and keep our servers humming without ads.

Thank you for supporting OpenCourser.

© 2016 - 2025 OpenCourser