diff --git a/27/404.html b/27/404.html index c3732fa1..931efdc4 100644 --- a/27/404.html +++ b/27/404.html @@ -4,13 +4,13 @@ Page Not Found | Hardware Software Interface - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/27/Labs/index.html b/27/Labs/index.html index 7250f692..db7bcd3c 100644 --- a/27/Labs/index.html +++ b/27/Labs/index.html @@ -4,13 +4,13 @@ Labs | Hardware Software Interface - +
Skip to main content
- + \ No newline at end of file diff --git a/27/Labs/lab1/index.html b/27/Labs/lab1/index.html index f7ce8077..d3c7a03d 100644 --- a/27/Labs/lab1/index.html +++ b/27/Labs/lab1/index.html @@ -4,7 +4,7 @@ Lab 1 - Number Representation | Hardware Software Interface - + @@ -27,7 +27,7 @@ Therefore, to convert a number from hexadecimal to binary, it's sufficient to transform each digit into the equivalent 4-bit group.

Example: Conversion of the number 0xD9B1 to binary

Thus, the resulting binary number is 0b1101100110110001.

The reverse operation, conversion from binary to hexadecimal, can be done by converting each group of 4 bits into the corresponding digit in hexadecimal.

Use of Base 16 Representation

The hexadecimal system is used to represent memory addresses and to visualize data in a more interpretable way than a sequence composed only of 0s and 1s. The image below provides an example in this regard:

Memory Map

(Image taken from Digital Detective)

Representation of Data Types

In a computer's memory, a value is stored on a fixed number of bits. Depending on the architecture, each processor can access a maximum number of bits in a single operation, which represents the word size.

The sizes of common data types used in C are dependent on both the processor and the platform on which the program was compiled (operating system, compiler). -The table below presents the sizes of data types on a 32-bit architecture processor, when the program is compiled using gcc under Linux.

On the left side of the image [above(), we have memory addresses where data is located. +The table below presents the sizes of data types on a 32-bit architecture processor, when the program is compiled using gcc under Linux.

On the left side of the image above, we have memory addresses where data is located. At address 0x0009FA08, the first 4 bytes starting from offset 0x02 are 0x01 0x00, 0xFF, 0xFF. These can represent a 4-byte integer, 4 characters, or 2 integers on 2 bytes. By using base 16, we can interpret the data and infer what they might represent.

The table below shows the sizes of data types on a 32-bit processor.

Data TypeNumber of BitsNumber of Bytes
char81
short162
int324
size_t324
long324
long long648
pointer324

On a 64-bit machine, the table above still holds true except for the types below. @@ -37,7 +37,7 @@ A void pointer differs from a pointer to an explicit data type in that a void pointer CANNOT be used in pointer operations, as void does not have a clear size. A basic example where pointers and pointer operations are used is the allocation and traversal of an array of values:

##include <stdio.h>
##include <stdlib.h>

##define ARR_LENGTH 5

int main()
{
int *arr, i;

arr = (int *)malloc(sizeof(int) * ARR_LENGTH);
// arr = (int *)calloc(ARR_LENGTH, sizeof(int));

for (i = 0; i < ARR_LENGTH; ++i) {
/*
* arr + i iterates through the addresses of each element in the array, but the address arr + i doesn't increase by i but by i * sizeof(int), as arr is a pointer to int
* This operation is not visible or necessary in C but will be required later in assembly language
*/
printf("arr[%d] = %d: ", i, *(arr + i));
}

free(arr);
return 0;
}

Pointers offer great flexibility regarding memory access. Below is an example that checks if a system is little or big endian using casting between different types of pointers.

##include <stdio.h>

int main()
{
int v = 0x00000001;
unsigned char *first_byte = (unsigned char *)&v;

if (*first_byte == 0x01)
printf("little-endian\n");
else
printf("big-endian\n");

return 0;
}
- + \ No newline at end of file diff --git a/27/Labs/lab11/index.html b/27/Labs/lab11/index.html index fde591bd..c76c8b8d 100644 --- a/27/Labs/lab11/index.html +++ b/27/Labs/lab11/index.html @@ -4,7 +4,7 @@ Lab 11 - Buffer Management. Buffer Overflow | Hardware Software Interface - + @@ -112,7 +112,7 @@ These values are generated and placed within the executable by the compiler and differ with each run of the executable. When an attacker tries to overwrite the return address, they will also overwrite the canary value, and before exiting the current function call, it will be checked whether that value has been modified or not. If it has been modified, it means that a buffer overflow has occurred, and the program execution will be interrupted.

This mechanism is called Stack Smashing Protection or Stack Guard. More details about Stack Guard and buffer overflow attacks can be found here.

- + \ No newline at end of file diff --git a/27/Labs/lab2/index.html b/27/Labs/lab2/index.html index 2f034d95..cbc6d462 100644 --- a/27/Labs/lab2/index.html +++ b/27/Labs/lab2/index.html @@ -4,7 +4,7 @@ Lab 2 - Memory Operations. Introduction to GDB | Hardware Software Interface - + @@ -82,7 +82,7 @@ If you have entered a large value for n and want to skip the iteration, use the continue command. Eventually, you will reach the line v[423433] = 3;, and GDB will display:

Program received signal SIGSEGV, Segmentation fault

Inspect the memory at v[423433] using x &v[423433] and you will receive the message:

Cannot access memory at address 0x5555558f3e94 /* The memory address should not be the same */

What happened? We accessed a memory area with restricted access.

- + \ No newline at end of file diff --git a/27/Labs/lab4/index.html b/27/Labs/lab4/index.html index 136d8406..231de35f 100644 --- a/27/Labs/lab4/index.html +++ b/27/Labs/lab4/index.html @@ -4,7 +4,7 @@ Lab 4 - Toolchain. GOTO | Hardware Software Interface - + @@ -68,7 +68,7 @@ This causes the interpretation of both parameters as long, as all parameters, regardless of type (int or pointer), are manipulated identically. The calculation param_2 + 8 is used to calculate the address of the second pointer in the argv vector (that is, argv[1]). For a program compiled for the 32-bit x86 architecture, the address of argv[1] would have been param_2 + 4.

Using the information from the decompiled code, we can infer that the program expects a password as an argument, and it must be 8 characters long, with the character at position 3 being 'E' (the first character is at position zero).

- + \ No newline at end of file diff --git a/27/Labs/lab5/index.html b/27/Labs/lab5/index.html index 377e9159..c01ebb46 100644 --- a/27/Labs/lab5/index.html +++ b/27/Labs/lab5/index.html @@ -4,7 +4,7 @@ Lab 5 - Introduction to Assembly Language | Hardware Software Interface - + @@ -43,7 +43,7 @@ It cannot be directly modified, programmatically, but indirectly through jump, call, and ret instructions.

The eflags register contains 32 bits used as status indicators or condition variables. We say that a flag is set if its value is 1. The ones commonly used by programmers are:

NameExpanded NameDescription
CFCarry FlagSet if the result exceeds the maximum (or minimum) unsigned integer value
PFParity FlagSet if the low byte of the result contains an even number of 1 bits
AFAuxiliary Carry FlagUsed in BCD arithmetic; set if bit 3 generates a carry or borrow
ZFZero FlagSet if the result of the previous instruction is 0
SFSign FlagHas the same value as the sign bit of the result (1 negative, 0 positive)
OFOverflow FlagSet if the result exceeds the maximum (or minimum) signed integer value

NOTE: If you follow the evolution of registers from 8086, you'll see that initially they were named ax, bx, cx etc., and were 16 bits in size. From 80386, Intel extended these registers to 32 bits (i.e., "extended" axeax).

Instruction Classes

Although the current set of instructions for Intel processors has hundreds of instructions, we will only look at a small portion of them. -More precisely, some of the 80386 instructions.

All x86 processors instructions can fit into 3 categories :

We will only display some of the more important instructions of each category since many of them are alike.

Data Movement Instructions

These instructions are used to transfer data between registers, between memory and registers, and to initialize data:

NameOperandsDescription
movdst, srcMoves the value from source to the destination(erasing what was in the destination before)
pushsrcMoves the value from the source onto the "top" of the stack
popdstMoves the value from the "top" of the stack into the destination
leadst, srcLoads the effective address of the source to the destination
xchgdst, srcSwaps(Exchanges) the values between the source and the destination

Arithmetic and Logic Instructions

These instructions perform arithmetic and logic operations:

NameOperandsDescription
adddst, srcAdds the source and the destination, storing the result in the destination
subdst, srcSubtracts the source from the destination, storing the result in the destination
anddst, srcCalculates logical AND between the source and the destination, storing the result in the destination
ordst, srcCalculates logical OR between the source and the destination, storing the result in the destination
xordst, srcCalculates logical XOR between the source and the destination, storing the result in the destination
testdst, srcCalculates logical AND between the source and the destination without storing the result
shldst, <const>Calculates the logical shifted value from the destination with a constant number of positions, storing the result in the destination

Program Control Instructions

These instructions are used to control the flow of programs:

NameOperandsDescription
jmp<address>Jumps unconditionally to the specified address(directly, by register, by labels)
cmpdst, srcCompares the source with the destination(more details below)
jcond<address>Jumps conditionally to the specified address depending on the state of the flag(set/not set)/condition variable
call<address>Calls the subroutine located at the specified address

NOTE: The 'cmp dest, src' instruction effectively calculates dest - src behind the scenes(as in subtracting the source from the destination). +More precisely, some of the 80386 instructions.

All x86 processors instructions can fit into 3 categories :

We will only display some of the more important instructions of each category since many of them are alike.

Data Movement Instructions

These instructions are used to transfer data between registers, between memory and registers, and to initialize data:

NameOperandsDescription
movdst, srcMoves the value from source to the destination(erasing what was in the destination before)
pushsrcMoves the value from the source onto the "top" of the stack
popdstMoves the value from the "top" of the stack into the destination
leadst, srcLoads the effective address of the source to the destination
xchgdst, srcSwaps (Exchanges) the values between the source and the destination

Arithmetic and Logic Instructions

These instructions perform arithmetic and logic operations:

NameOperandsDescription
adddst, srcAdds the source and the destination, storing the result in the destination
subdst, srcSubtracts the source from the destination, storing the result in the destination
anddst, srcCalculates logical AND between the source and the destination, storing the result in the destination
ordst, srcCalculates logical OR between the source and the destination, storing the result in the destination
xordst, srcCalculates logical XOR between the source and the destination, storing the result in the destination
testdst, srcCalculates logical AND between the source and the destination without storing the result
shldst, <const>Calculates the logical shifted value from the destination with a constant number of positions, storing the result in the destination

Program Control Instructions

These instructions are used to control the flow of programs:

NameOperandsDescription
jmp<address>Jumps unconditionally to the specified address(directly, by register, by labels)
cmpdst, srcCompares the source with the destination(more details below)
jcond<address>Jumps conditionally to the specified address depending on the state of the flag(set/not set)/condition variable
call<address>Calls the subroutine located at the specified address

NOTE: The 'cmp dest, src' instruction effectively calculates dest - src behind the scenes(as in subtracting the source from the destination). We are talking about an unsigned subtraction, without storing the result.

Therefore, when talking about the code:

  cmp eax, 0
jl negative

The jump to the negative label will be made only if the value in eax is less than 0. The eax - 0 subtraction is evaluated and if the result is negative(and so, eax is negative), the jump will be made.\ When have comparisons with 0, the same thing can be done more efficiently using the test instruction:

  test eax, eax
jl negative

More on this here.

Guide: First look at Assembly instructions

To follow this guide, you will need to use the instructions.asm file located in the guides/instructions/support directory.

Diving right into the demo, we can see one of the most important instructions that helps us, programmers, work with the stack and that is push. @@ -74,7 +74,7 @@ Because the je instruction jumps if the ZF bit in the FLAGS register is set. This bit is set by the cmp instruction, which calculates the difference between the values of the eax and ebx registers without storing the result. However, the add instruction at line 11 clears this flag because the result of the operation is different from 0.

- + \ No newline at end of file diff --git a/27/Labs/lab6/index.html b/27/Labs/lab6/index.html index e0b35900..026b0d98 100644 --- a/27/Labs/lab6/index.html +++ b/27/Labs/lab6/index.html @@ -4,7 +4,7 @@ Lab 6 - Registers and Memory Addressing | Hardware Software Interface - + @@ -45,7 +45,7 @@ There are other forms of the instruction that additionally check the ZF flag:

MnemonicDescription
loope/loopz labelDecrement ecx, jump to label if ecx != 0 and ZF == 1
loopne/loopnz labelDecrement ecx, jump to label if ecx != 0 and ZF != 1

NOTE: When using jumps in an assembly language program, it's important to consider the difference between a short jump (near jump) and a long jump (far jump).

Type and exampleSize and significanceDescription
Short Jump (loop)2 bytes (one byte for the opcode and one for the address)The relative address of the instruction to which the jump is intended must not be more than 128 bytes away from the current instruction address.
Long Jump (jmp)3 bytes (one byte for the opcode and two for the address)The relative address of the instruction to which the jump is intended must not be more than 32768 bytes away from the current instruction address.

Guide: Addressing Arrays

To follow this guide, you'll need to use the addressing_arrays.asm file located in the guides/addressing-arrays/support directory.

The program increments the values of an array of 10 integers by 1 and iterates through the array before and after to show the changes.

Note: ecx is used as the loop counter. Since the array contains dwords (4 bytes), the loop counter is multiplied by 4 to get the address of the next element in the array.

Guide: Declarations

To follow this guide, you'll need to use the declarations.asm file located in the guides/declarations/support directory.

The program declares multiple variables of different sizes in the .bss and .data sections.

Note: When defining strings, make sure to add a zero byte at the end, in order to mark the end of the string.

decimal_point   db ".",0

For a complete set of the pseudo-instruction check out the nasm documentation.

Guide: Loop

To follow this guide, you'll need to use the loop.asm file located in the guides/loop/support directory.

This program illustrates how to use the loop instruction, as well as how to index an array of dwords.

Note: The loop instruction jumps to the given label when the count register is not equal to 0. In the case of x86 the count register is ecx.

Note: For a detailed description of the loop instruction check out the documentation.

- + \ No newline at end of file diff --git a/27/Labs/lab7/index.html b/27/Labs/lab7/index.html index 871caf3f..4a46026b 100644 --- a/27/Labs/lab7/index.html +++ b/27/Labs/lab7/index.html @@ -4,7 +4,7 @@ Lab 7 - Structures, vectors and strings | Hardware Software Interface - + @@ -35,7 +35,7 @@ We can print the values from both fields of each element in the array with the following program:

struc   point
.x: resd 1
.y: resd 1
endstruc

section .data
point_array: times point_size * 100 db 0

section .text
global CMAIN

CMAIN:
push ebp
mov ebp, esp

xor edx, edx
xor eax, eax

label:
mov edx, [point_array + point_size * eax + point.x] ; access x member
PRINTF32 `%u\n\x0`, edx

mov edx, [point_array + point_size * eax + point.y] ; access y member
PRINTF32 `%u\n\x0`, edx

inc eax ; increment input index
cmp eax, 100
jl label

leave
ret

Guide: Max

To follow this guide, you'll need to use the max.asm file located in the guides/max/support directory.

The program finds the maximum value in an array of 16-bit integers (array). It iterates through the array, updating the maximum value (dx) when it finds a larger value. Finally, it prints the maximum value using the printf() function.

Note: For a detailed description of the instruction, check out the following page: Assembly Arrays Tutorial

- + \ No newline at end of file diff --git a/27/assets/files/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png b/27/assets/files/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png new file mode 100644 index 00000000..3b2a208b Binary files /dev/null and b/27/assets/files/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png differ diff --git a/27/assets/js/137b52b7.ff676f8b.js b/27/assets/js/137b52b7.dcf58f32.js similarity index 75% rename from 27/assets/js/137b52b7.ff676f8b.js rename to 27/assets/js/137b52b7.dcf58f32.js index 31d84b05..d1516084 100644 --- a/27/assets/js/137b52b7.ff676f8b.js +++ b/27/assets/js/137b52b7.dcf58f32.js @@ -1 +1 @@ -"use strict";(self.webpackChunkhardware_software_interface=self.webpackChunkhardware_software_interface||[]).push([[348],{5680:(e,a,n)=>{n.d(a,{xA:()=>o,yg:()=>d});var t=n(6540);function r(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function s(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var a=1;a=0||(r[n]=e[n]);return r}(e,a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var m=t.createContext({}),l=function(e){var a=t.useContext(m),n=a;return e&&(n="function"==typeof e?e(a):i(i({},a),e)),n},o=function(e){var a=l(e.components);return t.createElement(m.Provider,{value:a},e.children)},g="mdxType",y={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},c=t.forwardRef((function(e,a){var n=e.components,r=e.mdxType,s=e.originalType,m=e.parentName,o=p(e,["components","mdxType","originalType","parentName"]),g=l(n),c=r,d=g["".concat(m,".").concat(c)]||g[c]||y[c]||s;return n?t.createElement(d,i(i({ref:a},o),{},{components:n})):t.createElement(d,i({ref:a},o))}));function d(e,a){var n=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=c;var p={};for(var m in a)hasOwnProperty.call(a,m)&&(p[m]=a[m]);p.originalType=e,p[g]="string"==typeof e?e:r,i[1]=p;for(var l=2;l{n.r(a),n.d(a,{assets:()=>m,contentTitle:()=>i,default:()=>y,frontMatter:()=>s,metadata:()=>p,toc:()=>l});var t=n(8168),r=(n(6540),n(5680));const s={},i="Lab 1 - Number Representation",p={unversionedId:"Labs/lab1",id:"Labs/lab1",title:"Lab 1 - Number Representation",description:"Task: Conversions",source:"@site/docs/Labs/lab1.md",sourceDirName:"Labs",slug:"/Labs/lab1",permalink:"/hardware-software-interface/27/Labs/lab1",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Labs",permalink:"/hardware-software-interface/27/Labs/"},next:{title:"Lab 2 - Memory Operations. Introduction to GDB",permalink:"/hardware-software-interface/27/Labs/lab2"}},m={},l=[{value:"Task: Conversions",id:"task-conversions",level:2},{value:"Task: Rotations",id:"task-rotations",level:2},{value:"Task: Binary Even and Hexadecimal Odd",id:"task-binary-even-and-hexadecimal-odd",level:2},{value:"Task: Length and Equality with Bitwise Operations",id:"task-length-and-equality-with-bitwise-operations",level:2},{value:"Task: Reversing a String",id:"task-reversing-a-string",level:2},{value:"Binary and Hexadecimal Systems",id:"binary-and-hexadecimal-systems",level:2},{value:"Binary System",id:"binary-system",level:3},{value:"Operations with Values Represented in Binary",id:"operations-with-values-represented-in-binary",level:4},{value:"Arithmetic Operations",id:"arithmetic-operations",level:5},{value:"Logical Operations",id:"logical-operations",level:4},{value:"Operators on Binary Values",id:"operators-on-binary-values",level:5},{value:"Logical Shifts",id:"logical-shifts",level:5},{value:"Hexadecimal System",id:"hexadecimal-system",level:3},{value:"Conversion from Decimal to Binary/Hexadecimal",id:"conversion-from-decimal-to-binaryhexadecimal",level:4},{value:"Example: Conversion of the number 0xD9B1 to decimal",id:"example-conversion-of-the-number-0xd9b1-to-decimal",level:5},{value:"Conversion between Binary and Hexadecimal",id:"conversion-between-binary-and-hexadecimal",level:4},{value:"Example: Conversion of the number 0xD9B1 to binary",id:"example-conversion-of-the-number-0xd9b1-to-binary",level:5},{value:"Use of Base 16 Representation",id:"use-of-base-16-representation",level:4},{value:"Representation of Data Types",id:"representation-of-data-types",level:3},{value:"Order of Representation for Numbers Larger than One Byte (Little-Endian vs Big-Endian)",id:"order-of-representation-for-numbers-larger-than-one-byte-little-endian-vs-big-endian",level:3},{value:"Pointers in C",id:"pointers-in-c",level:2},{value:"Advantages of Pointers",id:"advantages-of-pointers",level:3},{value:"Disadvantages of Pointers",id:"disadvantages-of-pointers",level:3}],o={toc:l},g="wrapper";function y(e){let{components:a,...s}=e;return(0,r.yg)(g,(0,t.A)({},o,s,{components:a,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"lab-1---number-representation"},"Lab 1 - Number Representation"),(0,r.yg)("h2",{id:"task-conversions"},"Task: Conversions"),(0,r.yg)("p",null,"Perform the following conversions between numbering systems:"),(0,r.yg)("p",null,"a. From decimal to binary and hexadecimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"121")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"18446"))),(0,r.yg)("p",null,"b. Convert to decimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b1100010111010010")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xBB29"))),(0,r.yg)("p",null,"c. From hexadecimal to binary:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x5E")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x4A01"))),(0,r.yg)("p",null,"d. From binary to hexadecimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b01111101")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b1000110000011111"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-rotations"},"Task: Rotations"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"rotations.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/rotations/"),"."),(0,r.yg)("p",null,"Implement left and right rotations for 32-bit integers in C."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),": The rotation operation (also known as circular shift) is similar to the shift operation, with the only difference being that the empty space generated by the shift is filled with the discarded bit."),(0,r.yg)("p",{parentName:"blockquote"},"Example of ",(0,r.yg)("strong",{parentName:"p"},"left")," rotation by ",(0,r.yg)("strong",{parentName:"p"},"one")," bit:"),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("img",{alt:"Left Logical Rotation",src:n(9435).A})),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),":"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-c"},"rotate_left(0x80000000, 1) = 1\nrotate_right(0x00000001, 16) = 65536\n"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-binary-even-and-hexadecimal-odd"},"Task: Binary Even and Hexadecimal Odd"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"odd_even.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/odd-even/"),"."),(0,r.yg)("p",null,"Traverse an array of 32-bit integers using pointer operations and display the even numbers in binary and the odd numbers in hexadecimal."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Use bitwise operations wherever possible in your solution!"),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": For the array ",(0,r.yg)("inlineCode",{parentName:"p"},"[214, 71, 84, 134, 86]"),", the program will display:"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b11010110\n0x00000047\n0b01010100\n0b10000110\n0b01010110\n"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-length-and-equality-with-bitwise-operations"},"Task: Length and Equality with Bitwise Operations"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"len_xor.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/len-xor/support/"),"."),(0,r.yg)("p",null,"For a given string of characters, display:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"the length of the string"),(0,r.yg)("li",{parentName:"ul"},"the address of each character at position i that is equal to the character at position ",(0,r.yg)("span",{parentName:"li",className:"math math-inline"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mi",{parentName:"mrow"},"i"),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"2"),(0,r.yg)("mi",{parentName:"msup"},"i"))),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"i + 2^i")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.7429em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8247em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"2"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8247em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))))))," (if ",(0,r.yg)("span",{parentName:"li",className:"math math-inline"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mi",{parentName:"mrow"},"i"),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"2"),(0,r.yg)("mi",{parentName:"msup"},"i"))),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"i + 2^i")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.7429em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8247em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"2"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8247em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))))))," exceeds the size of the string, use the modulo operation)")),(0,r.yg)("p",null,"Use pointer operations and bitwise operations as much as possible!"),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Do not use functions such as ",(0,r.yg)("inlineCode",{parentName:"p"},"strlen()"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"sizeof()"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"pow()"),", and do not check equality using ",(0,r.yg)("inlineCode",{parentName:"p"},"=="),".\nAlso, do not access string elements in the form of ",(0,r.yg)("inlineCode",{parentName:"p"},"s[i]"),"."),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),': For the string "aac":'),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"length = 3\nAddress of a: 0x564c364482a0\nAddress of a: 0x564c364482a1\n")),(0,r.yg)("p",{parentName:"blockquote"},'For the string "ababababacccbacbacbacbacbabc":'),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"length = 28\nAddress of b: 0x563f0da6f2a1\nAddress of a: 0x563f0da6f2a2\nAddress of c: 0x563f0da6f2a9\nAddress of a: 0x563f0da6f2b0\nAddress of b: 0x563f0da6f2b2\nAddress of b: 0x563f0da6f2b5\nAddress of c: 0x563f0da6f2b7\nAddress of a: 0x563f0da6f2b9\n")),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"The above addresses are illustrative!"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#pointers-in-c"},"this")," reading material."),(0,r.yg)("h2",{id:"task-reversing-a-string"},"Task: Reversing a String"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"mirror.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/mirror/support/"),"."),(0,r.yg)("p",null,"Using pointer operations, implement a C program that reverses a string of characters.\nThe ",(0,r.yg)("inlineCode",{parentName:"p"},"mirror")," function should perform an ",(0,r.yg)("strong",{parentName:"p"},"in-place")," reversal of the characters in the string (upon exiting the function, the input string will contain the reversed string)."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Do not access string elements using the form ",(0,r.yg)("inlineCode",{parentName:"p"},"s[i]"),"."),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),":"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-c"},'mirror("AnaAreMere") = "ereMerAanA"\n\nmirror("asdfghjl") = "ljhgfdsa"\n\nmirror("qwerty") = "ytrewq"\n'))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#pointers-in-c"},"this")," reading material."),(0,r.yg)("h2",{id:"binary-and-hexadecimal-systems"},"Binary and Hexadecimal Systems"),(0,r.yg)("p",null,"For representing information (instructions and data), computers use the binary system (base 2).\nWhen writing programs in assembly language, the hexadecimal system (base 16) is preferred because it saves the programmer from writing long strings of 1s and 0s, and conversion to/from binary can be done much more easily than with the decimal system (base 10)."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": We'll use the prefix ",(0,r.yg)("inlineCode",{parentName:"p"},"0b")," for representing numbers in binary and ",(0,r.yg)("inlineCode",{parentName:"p"},"0x")," for hexadecimal numbers.\nFor example, we can write the unsigned integer ",(0,r.yg)("inlineCode",{parentName:"p"},"127")," as ",(0,r.yg)("inlineCode",{parentName:"p"},"0b01111111")," or ",(0,r.yg)("inlineCode",{parentName:"p"},"0x7F"),".")),(0,r.yg)("h3",{id:"binary-system"},"Binary System"),(0,r.yg)("p",null,"In the ",(0,r.yg)("strong",{parentName:"p"},"binary system")," (base 2), values are represented as a string of 0s and 1s.\nEach digit in the string represents a bit, and a group of 8 bits forms a byte.\nA group of 4 bits is called a ",(0,r.yg)("strong",{parentName:"p"},"nibble")," or ",(0,r.yg)("strong",{parentName:"p"},"half-byte"),"."),(0,r.yg)("h4",{id:"operations-with-values-represented-in-binary"},"Operations with Values Represented in Binary"),(0,r.yg)("h5",{id:"arithmetic-operations"},"Arithmetic Operations"),(0,r.yg)("p",null,"Arithmetic operations are the classic ",(0,r.yg)("inlineCode",{parentName:"p"},"+"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"-"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"*"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"/")," (integer division), ",(0,r.yg)("inlineCode",{parentName:"p"},"%")," (modulo).\nFundamentally they work the same way in any base 10, 2, 16 etc.\nJust keep in mind what the maximum digit is for each of these bases so you know when to carry or subtract 1 to or from the higher-order digit of the result or operand."),(0,r.yg)("p",null,"You can find a few examples of arithmetic operations in base 2 ",(0,r.yg)("a",{parentName:"p",href:"https://www.tutorialspoint.com/computer_logical_organization/binary_arithmetic.htm"},"here")),(0,r.yg)("h4",{id:"logical-operations"},"Logical Operations"),(0,r.yg)("h5",{id:"operators-on-binary-values"},"Operators on Binary Values"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"NOT Operation"),":\nInverts each bit.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"INV(0b10011010) = 0b01100101\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Logical AND Operation"),":\nPerforms the 'and' operation between bits at the same positions in operands.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 AND 0b0111 = 0b0001\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Logical OR Operation"),":\nPerforms the 'or' operation between bits at the same positions in operands.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 OR 0b0111 = 0b1111\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Exclusive OR (XOR) Operation"),":")),(0,r.yg)("p",null,"If bits at the same positions in operands have equal values, the resulting bit is 0;\notherwise, it's 1."),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 XOR 0b0111 = 0b1110\n")),(0,r.yg)("h5",{id:"logical-shifts"},"Logical Shifts"),(0,r.yg)("p",null,"Logical shifts left/right involve moving each bit by one position.\nSince the result must be on the same number of bits as the initial value, the first bit is lost, and the empty space is filled with a 0 bit."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Left Logical Shift",src:n(3967).A})),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Right Logical Shift",src:n(4916).A})),(0,r.yg)("p",null,"For explanations related to bitwise operations in C, refer to the guide at ",(0,r.yg)("a",{parentName:"p",href:"https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/"},"Bitwise Operators in C"),"."),(0,r.yg)("h3",{id:"hexadecimal-system"},"Hexadecimal System"),(0,r.yg)("p",null,"In the ",(0,r.yg)("strong",{parentName:"p"},"hexadecimal system")," (base 16), values are represented as a string of characters from '0' to '9' or 'a' to 'f'.\nA byte consists of two such characters, so each character corresponds to a group of 4 bits (a nibble)."),(0,r.yg)("h4",{id:"conversion-from-decimal-to-binaryhexadecimal"},"Conversion from Decimal to Binary/Hexadecimal"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Divide the number successively by the base number (2 or 16) and keep the remainders."),(0,r.yg)("li",{parentName:"ul"},"When the quotient of the division becomes 0, write down the remainders in reverse order."),(0,r.yg)("li",{parentName:"ul"},"In the case of base 16, when the remainder is greater than 9, letters a-f are used (",(0,r.yg)("inlineCode",{parentName:"li"},"0xa = 10"),", ",(0,r.yg)("inlineCode",{parentName:"li"},"0xf = 15"),").")),(0,r.yg)("h5",{id:"example-conversion-of-the-number-0xd9b1-to-decimal"},"Example: Conversion of the number 0xD9B1 to decimal"),(0,r.yg)("div",{className:"math math-display"},(0,r.yg)("span",{parentName:"div",className:"katex-display"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mtext",{parentName:"mrow",mathvariant:"monospace"},"0xD9B1"),(0,r.yg)("mo",{parentName:"mrow"},"="),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"0")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"11"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"1")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"9"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"2")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"13"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"3")),(0,r.yg)("mo",{parentName:"mrow"},"="),(0,r.yg)("mn",{parentName:"mrow"},"55729")),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\texttt{0xD9B1} = 1 \\cdot 16 ^ 0 + 11 \\cdot 16 ^ 1 + 9 \\cdot 16 ^ 2 + 13 \\cdot 16 ^ 3 = 55729")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6111em"}}),(0,r.yg)("span",{parentName:"span",className:"mord text"},(0,r.yg)("span",{parentName:"span",className:"mord texttt"},"0xD9B1")),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.yg)("span",{parentName:"span",className:"mrel"},"="),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"0")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"11"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"1")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"9"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"2")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"13"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8641em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"3")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.yg)("span",{parentName:"span",className:"mrel"},"="),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"55729")))))),(0,r.yg)("h4",{id:"conversion-between-binary-and-hexadecimal"},"Conversion between Binary and Hexadecimal"),(0,r.yg)("p",null,"As mentioned earlier, a digit in a hexadecimal number corresponds to a group of 4 bits (a nibble).\nTherefore, to convert a number from hexadecimal to binary, it's sufficient to transform each digit into the equivalent 4-bit group."),(0,r.yg)("h5",{id:"example-conversion-of-the-number-0xd9b1-to-binary"},"Example: Conversion of the number 0xD9B1 to binary"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x1 = 0b0001")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xB = 0b1011")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x9 = 0b1001")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xD = 0b1101"))),(0,r.yg)("p",null,"Thus, the resulting binary number is ",(0,r.yg)("inlineCode",{parentName:"p"},"0b1101100110110001"),"."),(0,r.yg)("p",null,"The reverse operation, conversion from binary to hexadecimal, can be done by converting each group of 4 bits into the corresponding digit in hexadecimal."),(0,r.yg)("h4",{id:"use-of-base-16-representation"},"Use of Base 16 Representation"),(0,r.yg)("p",null,"The hexadecimal system is used to represent memory addresses and to visualize data in a more interpretable way than a sequence composed only of 0s and 1s.\nThe image below provides an example in this regard:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Memory Map",src:n(9297).A,width:"845",height:"475"})),(0,r.yg)("p",null,"(Image taken from ",(0,r.yg)("a",{parentName:"p",href:"https://www.digital-detective.net/"},"Digital Detective"),")"),(0,r.yg)("h3",{id:"representation-of-data-types"},"Representation of Data Types"),(0,r.yg)("p",null,"In a computer's memory, a value is stored on a fixed number of bits.\nDepending on the architecture, each processor can access a maximum number of bits in a single operation, which represents the word size."),(0,r.yg)("p",null,"The sizes of common data types used in C are dependent on both the processor and the platform on which the program was compiled (operating system, compiler).\nThe table below presents the sizes of data types on a 32-bit architecture processor, when the program is compiled using gcc under Linux."),(0,r.yg)("p",null,"On the left side of the image [above(), we have memory addresses where data is located.\nAt address ",(0,r.yg)("inlineCode",{parentName:"p"},"0x0009FA08"),", the first 4 bytes starting from offset ",(0,r.yg)("inlineCode",{parentName:"p"},"0x02")," are ",(0,r.yg)("inlineCode",{parentName:"p"},"0x01")," ",(0,r.yg)("inlineCode",{parentName:"p"},"0x00"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"0xFF"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"0xFF"),".\nThese can represent a 4-byte integer, 4 characters, or 2 integers on 2 bytes.\nBy using base 16, we can interpret the data and infer what they might represent."),(0,r.yg)("p",null,"The table below shows the sizes of data types on a 32-bit processor."),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Data Type"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bits"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bytes"))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"char")),(0,r.yg)("td",{parentName:"tr",align:"center"},"8"),(0,r.yg)("td",{parentName:"tr",align:"center"},"1")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"short")),(0,r.yg)("td",{parentName:"tr",align:"center"},"16"),(0,r.yg)("td",{parentName:"tr",align:"center"},"2")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"int")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"size_t")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"pointer"),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")))),(0,r.yg)("p",null,"On a 64-bit machine, the table above still holds true except for the types below.\nOn 64-bit processors, addresses are 64 bits wide, which obviously affects the size of pointers and ",(0,r.yg)("inlineCode",{parentName:"p"},"size_t"),"."),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Data Type"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bits"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bytes"))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"size_t")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"pointer"),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")))),(0,r.yg)("h3",{id:"order-of-representation-for-numbers-larger-than-one-byte-little-endian-vs-big-endian"},"Order of Representation for Numbers Larger than One Byte (Little-Endian vs Big-Endian)"),(0,r.yg)("p",null,"For representing values larger than one byte, there are two possible methods, both used in practice:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("p",{parentName:"li"},"Little-Endian: The least significant byte is stored first (bytes are stored in reverse order).\nThis model is used by the Intel x86 processor family.")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("p",{parentName:"li"},"Big-Endian: The most significant byte is stored first."))),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Example"),": We want to store the value 0x4a912480 in memory on 32 bits (4 bytes), starting at address ",(0,r.yg)("inlineCode",{parentName:"p"},"0x100"),", using both methods:"),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Method"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x100")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x101")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x102")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x103")))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"Little-Endian"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x80"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x24"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x91"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x4a")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"Big-Endian"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x4a"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x91"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x24"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x80")))),(0,r.yg)("h2",{id:"pointers-in-c"},"Pointers in C"),(0,r.yg)("p",null,"In the C language, a pointer is a variable whose value is the address of another variable.\nWe can think of a pointer as an intermediary, namely a variable that points to a final location or to another intermediary as shown in the image and code below."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Simple and double pointer",src:n(9411).A})),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},"##include \n\nint main()\n{\n int v;\n int *p; /* pointer to a 32-bit integer */\n int **pp; /* pointer to a pointer holding the address of a 32-bit integer */\n\n /* To access the address of a variable in C, we use the address-of operator '&' */\n p = &v; /* p holds the address of value v */\n pp = &p; /* pp holds the address of the address of value v */\n\n v = 69;\n /* To access the value at the address stored by a pointer, we use the dereference operator '*' */\n printf(\"v(%d) - *p(%d) - **pp(%d)\\n\", v, *p, *(*pp)); /* outputs v(69) - *p(69) - **pp(69) */\n\n return 0;\n}\n")),(0,r.yg)("h3",{id:"advantages-of-pointers"},"Advantages of Pointers"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Pointers are used in creating complex data structures such as linked lists, trees, graphs, hash tables, etc."),(0,r.yg)("li",{parentName:"ul"},"Pointers are used to transfer information between different functions or recursive calls without using global variables."),(0,r.yg)("li",{parentName:"ul"},"By using pointers, we can dynamically allocate memory."),(0,r.yg)("li",{parentName:"ul"},"We can have other functions, strings, complex data structures as parameters for functions.")),(0,r.yg)("h3",{id:"disadvantages-of-pointers"},"Disadvantages of Pointers"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Using an uninitialized pointer in a program leads to a ",(0,r.yg)("strong",{parentName:"li"},"segmentation fault")," by accessing a restricted memory area."),(0,r.yg)("li",{parentName:"ul"},"Manual memory deallocation is required by the programmer for dynamically allocated memory."),(0,r.yg)("li",{parentName:"ul"},"Dereferencing is needed to access a value, which is slower than direct access.")),(0,r.yg)("p",null,"In C, a pointer can be defined for any of the data types existing in the language as well as for ",(0,r.yg)("inlineCode",{parentName:"p"},"void"),".\nA ",(0,r.yg)("inlineCode",{parentName:"p"},"void")," pointer differs from a pointer to an explicit data type in that a void pointer ",(0,r.yg)("strong",{parentName:"p"},"CANNOT")," be used in pointer operations, as void does not have a clear size.\nA basic example where pointers and pointer operations are used is the allocation and traversal of an array of values:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},'##include \n##include \n\n##define ARR_LENGTH 5\n\nint main()\n{\n int *arr, i;\n\n arr = (int *)malloc(sizeof(int) * ARR_LENGTH);\n // arr = (int *)calloc(ARR_LENGTH, sizeof(int));\n\n for (i = 0; i < ARR_LENGTH; ++i) {\n /*\n * arr + i iterates through the addresses of each element in the array, but the address arr + i doesn\'t increase by i but by i * sizeof(int), as arr is a pointer to int\n * This operation is not visible or necessary in C but will be required later in assembly language\n */\n printf("arr[%d] = %d: ", i, *(arr + i));\n }\n\n free(arr);\n return 0;\n}\n')),(0,r.yg)("p",null,"Pointers offer great flexibility regarding memory access.\nBelow is an example that checks if a system is little or big endian using casting between different types of pointers."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},'##include \n\nint main()\n{\n int v = 0x00000001;\n unsigned char *first_byte = (unsigned char *)&v;\n\n if (*first_byte == 0x01)\n printf("little-endian\\n");\n else\n printf("big-endian\\n");\n\n return 0;\n}\n')))}y.isMDXComponent=!0},9297:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png"},9435:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/left-logical-rotation-f0583e0d308391ed199c78ffeddb9ffa.svg"},3967:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/left-logical-shift-8a7457b9b81e57808f65c343bdf0706f.svg"},4916:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/right-logical-shift-f622a1bc8014edbba4e5222fafabb919.svg"},9411:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/simple-double-pointer-be5d7f5c690a7a911d9143a94d2f3e7c.svg"}}]); \ No newline at end of file +"use strict";(self.webpackChunkhardware_software_interface=self.webpackChunkhardware_software_interface||[]).push([[348],{5680:(e,a,n)=>{n.d(a,{xA:()=>o,yg:()=>d});var t=n(6540);function r(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function s(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);a&&(t=t.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var a=1;a=0||(r[n]=e[n]);return r}(e,a);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var m=t.createContext({}),l=function(e){var a=t.useContext(m),n=a;return e&&(n="function"==typeof e?e(a):i(i({},a),e)),n},o=function(e){var a=l(e.components);return t.createElement(m.Provider,{value:a},e.children)},g="mdxType",y={inlineCode:"code",wrapper:function(e){var a=e.children;return t.createElement(t.Fragment,{},a)}},c=t.forwardRef((function(e,a){var n=e.components,r=e.mdxType,s=e.originalType,m=e.parentName,o=p(e,["components","mdxType","originalType","parentName"]),g=l(n),c=r,d=g["".concat(m,".").concat(c)]||g[c]||y[c]||s;return n?t.createElement(d,i(i({ref:a},o),{},{components:n})):t.createElement(d,i({ref:a},o))}));function d(e,a){var n=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var s=n.length,i=new Array(s);i[0]=c;var p={};for(var m in a)hasOwnProperty.call(a,m)&&(p[m]=a[m]);p.originalType=e,p[g]="string"==typeof e?e:r,i[1]=p;for(var l=2;l{n.r(a),n.d(a,{assets:()=>m,contentTitle:()=>i,default:()=>y,frontMatter:()=>s,metadata:()=>p,toc:()=>l});var t=n(8168),r=(n(6540),n(5680));const s={},i="Lab 1 - Number Representation",p={unversionedId:"Labs/lab1",id:"Labs/lab1",title:"Lab 1 - Number Representation",description:"Task: Conversions",source:"@site/docs/Labs/lab1.md",sourceDirName:"Labs",slug:"/Labs/lab1",permalink:"/hardware-software-interface/27/Labs/lab1",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Labs",permalink:"/hardware-software-interface/27/Labs/"},next:{title:"Lab 2 - Memory Operations. Introduction to GDB",permalink:"/hardware-software-interface/27/Labs/lab2"}},m={},l=[{value:"Task: Conversions",id:"task-conversions",level:2},{value:"Task: Rotations",id:"task-rotations",level:2},{value:"Task: Binary Even and Hexadecimal Odd",id:"task-binary-even-and-hexadecimal-odd",level:2},{value:"Task: Length and Equality with Bitwise Operations",id:"task-length-and-equality-with-bitwise-operations",level:2},{value:"Task: Reversing a String",id:"task-reversing-a-string",level:2},{value:"Binary and Hexadecimal Systems",id:"binary-and-hexadecimal-systems",level:2},{value:"Binary System",id:"binary-system",level:3},{value:"Operations with Values Represented in Binary",id:"operations-with-values-represented-in-binary",level:4},{value:"Arithmetic Operations",id:"arithmetic-operations",level:5},{value:"Logical Operations",id:"logical-operations",level:4},{value:"Operators on Binary Values",id:"operators-on-binary-values",level:5},{value:"Logical Shifts",id:"logical-shifts",level:5},{value:"Hexadecimal System",id:"hexadecimal-system",level:3},{value:"Conversion from Decimal to Binary/Hexadecimal",id:"conversion-from-decimal-to-binaryhexadecimal",level:4},{value:"Example: Conversion of the number 0xD9B1 to decimal",id:"example-conversion-of-the-number-0xd9b1-to-decimal",level:5},{value:"Conversion between Binary and Hexadecimal",id:"conversion-between-binary-and-hexadecimal",level:4},{value:"Example: Conversion of the number 0xD9B1 to binary",id:"example-conversion-of-the-number-0xd9b1-to-binary",level:5},{value:"Use of Base 16 Representation",id:"use-of-base-16-representation",level:4},{value:"Representation of Data Types",id:"representation-of-data-types",level:3},{value:"Order of Representation for Numbers Larger than One Byte (Little-Endian vs Big-Endian)",id:"order-of-representation-for-numbers-larger-than-one-byte-little-endian-vs-big-endian",level:3},{value:"Pointers in C",id:"pointers-in-c",level:2},{value:"Advantages of Pointers",id:"advantages-of-pointers",level:3},{value:"Disadvantages of Pointers",id:"disadvantages-of-pointers",level:3}],o={toc:l},g="wrapper";function y(e){let{components:a,...s}=e;return(0,r.yg)(g,(0,t.A)({},o,s,{components:a,mdxType:"MDXLayout"}),(0,r.yg)("h1",{id:"lab-1---number-representation"},"Lab 1 - Number Representation"),(0,r.yg)("h2",{id:"task-conversions"},"Task: Conversions"),(0,r.yg)("p",null,"Perform the following conversions between numbering systems:"),(0,r.yg)("p",null,"a. From decimal to binary and hexadecimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"121")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"18446"))),(0,r.yg)("p",null,"b. Convert to decimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b1100010111010010")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xBB29"))),(0,r.yg)("p",null,"c. From hexadecimal to binary:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x5E")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x4A01"))),(0,r.yg)("p",null,"d. From binary to hexadecimal:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b01111101")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0b1000110000011111"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-rotations"},"Task: Rotations"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"rotations.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/rotations/"),"."),(0,r.yg)("p",null,"Implement left and right rotations for 32-bit integers in C."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),": The rotation operation (also known as circular shift) is similar to the shift operation, with the only difference being that the empty space generated by the shift is filled with the discarded bit."),(0,r.yg)("p",{parentName:"blockquote"},"Example of ",(0,r.yg)("strong",{parentName:"p"},"left")," rotation by ",(0,r.yg)("strong",{parentName:"p"},"one")," bit:"),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("img",{alt:"Left Logical Rotation",src:n(9435).A})),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),":"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-c"},"rotate_left(0x80000000, 1) = 1\nrotate_right(0x00000001, 16) = 65536\n"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-binary-even-and-hexadecimal-odd"},"Task: Binary Even and Hexadecimal Odd"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"odd_even.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/odd-even/"),"."),(0,r.yg)("p",null,"Traverse an array of 32-bit integers using pointer operations and display the even numbers in binary and the odd numbers in hexadecimal."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Use bitwise operations wherever possible in your solution!"),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": For the array ",(0,r.yg)("inlineCode",{parentName:"p"},"[214, 71, 84, 134, 86]"),", the program will display:"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b11010110\n0x00000047\n0b01010100\n0b10000110\n0b01010110\n"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#binary-and-hexadecimal-systems"},"this")," reading material."),(0,r.yg)("h2",{id:"task-length-and-equality-with-bitwise-operations"},"Task: Length and Equality with Bitwise Operations"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"len_xor.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/len-xor/support/"),"."),(0,r.yg)("p",null,"For a given string of characters, display:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"the length of the string"),(0,r.yg)("li",{parentName:"ul"},"the address of each character at position i that is equal to the character at position ",(0,r.yg)("span",{parentName:"li",className:"math math-inline"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mi",{parentName:"mrow"},"i"),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"2"),(0,r.yg)("mi",{parentName:"msup"},"i"))),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"i + 2^i")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.7429em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8247em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"2"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8247em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))))))," (if ",(0,r.yg)("span",{parentName:"li",className:"math math-inline"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mi",{parentName:"mrow"},"i"),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"2"),(0,r.yg)("mi",{parentName:"msup"},"i"))),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"i + 2^i")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.7429em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8247em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"2"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8247em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))))))," exceeds the size of the string, use the modulo operation)")),(0,r.yg)("p",null,"Use pointer operations and bitwise operations as much as possible!"),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Do not use functions such as ",(0,r.yg)("inlineCode",{parentName:"p"},"strlen()"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"sizeof()"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"pow()"),", and do not check equality using ",(0,r.yg)("inlineCode",{parentName:"p"},"=="),".\nAlso, do not access string elements in the form of ",(0,r.yg)("inlineCode",{parentName:"p"},"s[i]"),"."),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),': For the string "aac":'),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"length = 3\nAddress of a: 0x564c364482a0\nAddress of a: 0x564c364482a1\n")),(0,r.yg)("p",{parentName:"blockquote"},'For the string "ababababacccbacbacbacbacbabc":'),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-text"},"length = 28\nAddress of b: 0x563f0da6f2a1\nAddress of a: 0x563f0da6f2a2\nAddress of c: 0x563f0da6f2a9\nAddress of a: 0x563f0da6f2b0\nAddress of b: 0x563f0da6f2b2\nAddress of b: 0x563f0da6f2b5\nAddress of c: 0x563f0da6f2b7\nAddress of a: 0x563f0da6f2b9\n")),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"The above addresses are illustrative!"))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#pointers-in-c"},"this")," reading material."),(0,r.yg)("h2",{id:"task-reversing-a-string"},"Task: Reversing a String"),(0,r.yg)("p",null,"You will solve the exercise starting from the file ",(0,r.yg)("inlineCode",{parentName:"p"},"mirror.c")," located in the directory ",(0,r.yg)("inlineCode",{parentName:"p"},"drills/tasks/mirror/support/"),"."),(0,r.yg)("p",null,"Using pointer operations, implement a C program that reverses a string of characters.\nThe ",(0,r.yg)("inlineCode",{parentName:"p"},"mirror")," function should perform an ",(0,r.yg)("strong",{parentName:"p"},"in-place")," reversal of the characters in the string (upon exiting the function, the input string will contain the reversed string)."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": Do not access string elements using the form ",(0,r.yg)("inlineCode",{parentName:"p"},"s[i]"),"."),(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"TIP"),":"),(0,r.yg)("pre",{parentName:"blockquote"},(0,r.yg)("code",{parentName:"pre",className:"language-c"},'mirror("AnaAreMere") = "ereMerAanA"\n\nmirror("asdfghjl") = "ljhgfdsa"\n\nmirror("qwerty") = "ytrewq"\n'))),(0,r.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,r.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab1#pointers-in-c"},"this")," reading material."),(0,r.yg)("h2",{id:"binary-and-hexadecimal-systems"},"Binary and Hexadecimal Systems"),(0,r.yg)("p",null,"For representing information (instructions and data), computers use the binary system (base 2).\nWhen writing programs in assembly language, the hexadecimal system (base 16) is preferred because it saves the programmer from writing long strings of 1s and 0s, and conversion to/from binary can be done much more easily than with the decimal system (base 10)."),(0,r.yg)("blockquote",null,(0,r.yg)("p",{parentName:"blockquote"},(0,r.yg)("strong",{parentName:"p"},"NOTE"),": We'll use the prefix ",(0,r.yg)("inlineCode",{parentName:"p"},"0b")," for representing numbers in binary and ",(0,r.yg)("inlineCode",{parentName:"p"},"0x")," for hexadecimal numbers.\nFor example, we can write the unsigned integer ",(0,r.yg)("inlineCode",{parentName:"p"},"127")," as ",(0,r.yg)("inlineCode",{parentName:"p"},"0b01111111")," or ",(0,r.yg)("inlineCode",{parentName:"p"},"0x7F"),".")),(0,r.yg)("h3",{id:"binary-system"},"Binary System"),(0,r.yg)("p",null,"In the ",(0,r.yg)("strong",{parentName:"p"},"binary system")," (base 2), values are represented as a string of 0s and 1s.\nEach digit in the string represents a bit, and a group of 8 bits forms a byte.\nA group of 4 bits is called a ",(0,r.yg)("strong",{parentName:"p"},"nibble")," or ",(0,r.yg)("strong",{parentName:"p"},"half-byte"),"."),(0,r.yg)("h4",{id:"operations-with-values-represented-in-binary"},"Operations with Values Represented in Binary"),(0,r.yg)("h5",{id:"arithmetic-operations"},"Arithmetic Operations"),(0,r.yg)("p",null,"Arithmetic operations are the classic ",(0,r.yg)("inlineCode",{parentName:"p"},"+"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"-"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"*"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"/")," (integer division), ",(0,r.yg)("inlineCode",{parentName:"p"},"%")," (modulo).\nFundamentally they work the same way in any base 10, 2, 16 etc.\nJust keep in mind what the maximum digit is for each of these bases so you know when to carry or subtract 1 to or from the higher-order digit of the result or operand."),(0,r.yg)("p",null,"You can find a few examples of arithmetic operations in base 2 ",(0,r.yg)("a",{parentName:"p",href:"https://www.tutorialspoint.com/computer_logical_organization/binary_arithmetic.htm"},"here")),(0,r.yg)("h4",{id:"logical-operations"},"Logical Operations"),(0,r.yg)("h5",{id:"operators-on-binary-values"},"Operators on Binary Values"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"NOT Operation"),":\nInverts each bit.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"INV(0b10011010) = 0b01100101\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Logical AND Operation"),":\nPerforms the 'and' operation between bits at the same positions in operands.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 AND 0b0111 = 0b0001\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Logical OR Operation"),":\nPerforms the 'or' operation between bits at the same positions in operands.")),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 OR 0b0111 = 0b1111\n")),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("strong",{parentName:"li"},"Exclusive OR (XOR) Operation"),":")),(0,r.yg)("p",null,"If bits at the same positions in operands have equal values, the resulting bit is 0;\notherwise, it's 1."),(0,r.yg)("p",null,"Example:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-text"},"0b1001 XOR 0b0111 = 0b1110\n")),(0,r.yg)("h5",{id:"logical-shifts"},"Logical Shifts"),(0,r.yg)("p",null,"Logical shifts left/right involve moving each bit by one position.\nSince the result must be on the same number of bits as the initial value, the first bit is lost, and the empty space is filled with a 0 bit."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Left Logical Shift",src:n(3967).A})),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Right Logical Shift",src:n(4916).A})),(0,r.yg)("p",null,"For explanations related to bitwise operations in C, refer to the guide at ",(0,r.yg)("a",{parentName:"p",href:"https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/"},"Bitwise Operators in C"),"."),(0,r.yg)("h3",{id:"hexadecimal-system"},"Hexadecimal System"),(0,r.yg)("p",null,"In the ",(0,r.yg)("strong",{parentName:"p"},"hexadecimal system")," (base 16), values are represented as a string of characters from '0' to '9' or 'a' to 'f'.\nA byte consists of two such characters, so each character corresponds to a group of 4 bits (a nibble)."),(0,r.yg)("h4",{id:"conversion-from-decimal-to-binaryhexadecimal"},"Conversion from Decimal to Binary/Hexadecimal"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Divide the number successively by the base number (2 or 16) and keep the remainders."),(0,r.yg)("li",{parentName:"ul"},"When the quotient of the division becomes 0, write down the remainders in reverse order."),(0,r.yg)("li",{parentName:"ul"},"In the case of base 16, when the remainder is greater than 9, letters a-f are used (",(0,r.yg)("inlineCode",{parentName:"li"},"0xa = 10"),", ",(0,r.yg)("inlineCode",{parentName:"li"},"0xf = 15"),").")),(0,r.yg)("h5",{id:"example-conversion-of-the-number-0xd9b1-to-decimal"},"Example: Conversion of the number 0xD9B1 to decimal"),(0,r.yg)("div",{className:"math math-display"},(0,r.yg)("span",{parentName:"div",className:"katex-display"},(0,r.yg)("span",{parentName:"span",className:"katex"},(0,r.yg)("span",{parentName:"span",className:"katex-mathml"},(0,r.yg)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,r.yg)("semantics",{parentName:"math"},(0,r.yg)("mrow",{parentName:"semantics"},(0,r.yg)("mtext",{parentName:"mrow",mathvariant:"monospace"},"0xD9B1"),(0,r.yg)("mo",{parentName:"mrow"},"="),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"0")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"11"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"1")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"9"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"2")),(0,r.yg)("mo",{parentName:"mrow"},"+"),(0,r.yg)("mn",{parentName:"mrow"},"13"),(0,r.yg)("mo",{parentName:"mrow"},"\u22c5"),(0,r.yg)("mn",{parentName:"mrow"},"1"),(0,r.yg)("msup",{parentName:"mrow"},(0,r.yg)("mn",{parentName:"msup"},"6"),(0,r.yg)("mn",{parentName:"msup"},"3")),(0,r.yg)("mo",{parentName:"mrow"},"="),(0,r.yg)("mn",{parentName:"mrow"},"55729")),(0,r.yg)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\texttt{0xD9B1} = 1 \\cdot 16 ^ 0 + 11 \\cdot 16 ^ 1 + 9 \\cdot 16 ^ 2 + 13 \\cdot 16 ^ 3 = 55729")))),(0,r.yg)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6111em"}}),(0,r.yg)("span",{parentName:"span",className:"mord text"},(0,r.yg)("span",{parentName:"span",className:"mord texttt"},"0xD9B1")),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.yg)("span",{parentName:"span",className:"mrel"},"="),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"0")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"11"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"1")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"9"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.9474em",verticalAlign:"-0.0833em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"2")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"+"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"13"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,r.yg)("span",{parentName:"span",className:"mbin"},"\u22c5"),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.8641em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"1"),(0,r.yg)("span",{parentName:"span",className:"mord"},(0,r.yg)("span",{parentName:"span",className:"mord"},"6"),(0,r.yg)("span",{parentName:"span",className:"msupsub"},(0,r.yg)("span",{parentName:"span",className:"vlist-t"},(0,r.yg)("span",{parentName:"span",className:"vlist-r"},(0,r.yg)("span",{parentName:"span",className:"vlist",style:{height:"0.8641em"}},(0,r.yg)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,r.yg)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.yg)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.yg)("span",{parentName:"span",className:"mord mtight"},"3")))))))),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.yg)("span",{parentName:"span",className:"mrel"},"="),(0,r.yg)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.yg)("span",{parentName:"span",className:"base"},(0,r.yg)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.yg)("span",{parentName:"span",className:"mord"},"55729")))))),(0,r.yg)("h4",{id:"conversion-between-binary-and-hexadecimal"},"Conversion between Binary and Hexadecimal"),(0,r.yg)("p",null,"As mentioned earlier, a digit in a hexadecimal number corresponds to a group of 4 bits (a nibble).\nTherefore, to convert a number from hexadecimal to binary, it's sufficient to transform each digit into the equivalent 4-bit group."),(0,r.yg)("h5",{id:"example-conversion-of-the-number-0xd9b1-to-binary"},"Example: Conversion of the number 0xD9B1 to binary"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x1 = 0b0001")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xB = 0b1011")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0x9 = 0b1001")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("inlineCode",{parentName:"li"},"0xD = 0b1101"))),(0,r.yg)("p",null,"Thus, the resulting binary number is ",(0,r.yg)("inlineCode",{parentName:"p"},"0b1101100110110001"),"."),(0,r.yg)("p",null,"The reverse operation, conversion from binary to hexadecimal, can be done by converting each group of 4 bits into the corresponding digit in hexadecimal."),(0,r.yg)("h4",{id:"use-of-base-16-representation"},"Use of Base 16 Representation"),(0,r.yg)("p",null,"The hexadecimal system is used to represent memory addresses and to visualize data in a more interpretable way than a sequence composed only of 0s and 1s.\nThe image below provides an example in this regard:"),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Memory Map",src:n(9297).A,width:"845",height:"475"})),(0,r.yg)("p",null,"(Image taken from ",(0,r.yg)("a",{parentName:"p",href:"https://www.digital-detective.net/"},"Digital Detective"),")"),(0,r.yg)("h3",{id:"representation-of-data-types"},"Representation of Data Types"),(0,r.yg)("p",null,"In a computer's memory, a value is stored on a fixed number of bits.\nDepending on the architecture, each processor can access a maximum number of bits in a single operation, which represents the word size."),(0,r.yg)("p",null,"The sizes of common data types used in C are dependent on both the processor and the platform on which the program was compiled (operating system, compiler).\nThe table below presents the sizes of data types on a 32-bit architecture processor, when the program is compiled using gcc under Linux."),(0,r.yg)("p",null,"On the left side of the image ",(0,r.yg)("a",{target:"_blank",href:n(4469).A},"above"),", we have memory addresses where data is located.\nAt address ",(0,r.yg)("inlineCode",{parentName:"p"},"0x0009FA08"),", the first 4 bytes starting from offset ",(0,r.yg)("inlineCode",{parentName:"p"},"0x02")," are ",(0,r.yg)("inlineCode",{parentName:"p"},"0x01")," ",(0,r.yg)("inlineCode",{parentName:"p"},"0x00"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"0xFF"),", ",(0,r.yg)("inlineCode",{parentName:"p"},"0xFF"),".\nThese can represent a 4-byte integer, 4 characters, or 2 integers on 2 bytes.\nBy using base 16, we can interpret the data and infer what they might represent."),(0,r.yg)("p",null,"The table below shows the sizes of data types on a 32-bit processor."),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Data Type"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bits"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bytes"))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"char")),(0,r.yg)("td",{parentName:"tr",align:"center"},"8"),(0,r.yg)("td",{parentName:"tr",align:"center"},"1")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"short")),(0,r.yg)("td",{parentName:"tr",align:"center"},"16"),(0,r.yg)("td",{parentName:"tr",align:"center"},"2")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"int")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"size_t")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"pointer"),(0,r.yg)("td",{parentName:"tr",align:"center"},"32"),(0,r.yg)("td",{parentName:"tr",align:"center"},"4")))),(0,r.yg)("p",null,"On a 64-bit machine, the table above still holds true except for the types below.\nOn 64-bit processors, addresses are 64 bits wide, which obviously affects the size of pointers and ",(0,r.yg)("inlineCode",{parentName:"p"},"size_t"),"."),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Data Type"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bits"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Number of Bytes"))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"size_t")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},(0,r.yg)("inlineCode",{parentName:"td"},"long")),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"pointer"),(0,r.yg)("td",{parentName:"tr",align:"center"},"64"),(0,r.yg)("td",{parentName:"tr",align:"center"},"8")))),(0,r.yg)("h3",{id:"order-of-representation-for-numbers-larger-than-one-byte-little-endian-vs-big-endian"},"Order of Representation for Numbers Larger than One Byte (Little-Endian vs Big-Endian)"),(0,r.yg)("p",null,"For representing values larger than one byte, there are two possible methods, both used in practice:"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("p",{parentName:"li"},"Little-Endian: The least significant byte is stored first (bytes are stored in reverse order).\nThis model is used by the Intel x86 processor family.")),(0,r.yg)("li",{parentName:"ul"},(0,r.yg)("p",{parentName:"li"},"Big-Endian: The most significant byte is stored first."))),(0,r.yg)("p",null,(0,r.yg)("strong",{parentName:"p"},"Example"),": We want to store the value 0x4a912480 in memory on 32 bits (4 bytes), starting at address ",(0,r.yg)("inlineCode",{parentName:"p"},"0x100"),", using both methods:"),(0,r.yg)("table",null,(0,r.yg)("thead",{parentName:"table"},(0,r.yg)("tr",{parentName:"thead"},(0,r.yg)("th",{parentName:"tr",align:"center"},"Method"),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x100")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x101")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x102")),(0,r.yg)("th",{parentName:"tr",align:"center"},"Address ",(0,r.yg)("inlineCode",{parentName:"th"},"0x103")))),(0,r.yg)("tbody",{parentName:"table"},(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"Little-Endian"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x80"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x24"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x91"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x4a")),(0,r.yg)("tr",{parentName:"tbody"},(0,r.yg)("td",{parentName:"tr",align:"center"},"Big-Endian"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x4a"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x91"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x24"),(0,r.yg)("td",{parentName:"tr",align:"center"},"0x80")))),(0,r.yg)("h2",{id:"pointers-in-c"},"Pointers in C"),(0,r.yg)("p",null,"In the C language, a pointer is a variable whose value is the address of another variable.\nWe can think of a pointer as an intermediary, namely a variable that points to a final location or to another intermediary as shown in the image and code below."),(0,r.yg)("p",null,(0,r.yg)("img",{alt:"Simple and double pointer",src:n(9411).A})),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},"##include \n\nint main()\n{\n int v;\n int *p; /* pointer to a 32-bit integer */\n int **pp; /* pointer to a pointer holding the address of a 32-bit integer */\n\n /* To access the address of a variable in C, we use the address-of operator '&' */\n p = &v; /* p holds the address of value v */\n pp = &p; /* pp holds the address of the address of value v */\n\n v = 69;\n /* To access the value at the address stored by a pointer, we use the dereference operator '*' */\n printf(\"v(%d) - *p(%d) - **pp(%d)\\n\", v, *p, *(*pp)); /* outputs v(69) - *p(69) - **pp(69) */\n\n return 0;\n}\n")),(0,r.yg)("h3",{id:"advantages-of-pointers"},"Advantages of Pointers"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Pointers are used in creating complex data structures such as linked lists, trees, graphs, hash tables, etc."),(0,r.yg)("li",{parentName:"ul"},"Pointers are used to transfer information between different functions or recursive calls without using global variables."),(0,r.yg)("li",{parentName:"ul"},"By using pointers, we can dynamically allocate memory."),(0,r.yg)("li",{parentName:"ul"},"We can have other functions, strings, complex data structures as parameters for functions.")),(0,r.yg)("h3",{id:"disadvantages-of-pointers"},"Disadvantages of Pointers"),(0,r.yg)("ul",null,(0,r.yg)("li",{parentName:"ul"},"Using an uninitialized pointer in a program leads to a ",(0,r.yg)("strong",{parentName:"li"},"segmentation fault")," by accessing a restricted memory area."),(0,r.yg)("li",{parentName:"ul"},"Manual memory deallocation is required by the programmer for dynamically allocated memory."),(0,r.yg)("li",{parentName:"ul"},"Dereferencing is needed to access a value, which is slower than direct access.")),(0,r.yg)("p",null,"In C, a pointer can be defined for any of the data types existing in the language as well as for ",(0,r.yg)("inlineCode",{parentName:"p"},"void"),".\nA ",(0,r.yg)("inlineCode",{parentName:"p"},"void")," pointer differs from a pointer to an explicit data type in that a void pointer ",(0,r.yg)("strong",{parentName:"p"},"CANNOT")," be used in pointer operations, as void does not have a clear size.\nA basic example where pointers and pointer operations are used is the allocation and traversal of an array of values:"),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},'##include \n##include \n\n##define ARR_LENGTH 5\n\nint main()\n{\n int *arr, i;\n\n arr = (int *)malloc(sizeof(int) * ARR_LENGTH);\n // arr = (int *)calloc(ARR_LENGTH, sizeof(int));\n\n for (i = 0; i < ARR_LENGTH; ++i) {\n /*\n * arr + i iterates through the addresses of each element in the array, but the address arr + i doesn\'t increase by i but by i * sizeof(int), as arr is a pointer to int\n * This operation is not visible or necessary in C but will be required later in assembly language\n */\n printf("arr[%d] = %d: ", i, *(arr + i));\n }\n\n free(arr);\n return 0;\n}\n')),(0,r.yg)("p",null,"Pointers offer great flexibility regarding memory access.\nBelow is an example that checks if a system is little or big endian using casting between different types of pointers."),(0,r.yg)("pre",null,(0,r.yg)("code",{parentName:"pre",className:"language-c"},'##include \n\nint main()\n{\n int v = 0x00000001;\n unsigned char *first_byte = (unsigned char *)&v;\n\n if (*first_byte == 0x01)\n printf("little-endian\\n");\n else\n printf("big-endian\\n");\n\n return 0;\n}\n')))}y.isMDXComponent=!0},4469:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/files/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png"},9297:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/hex-view-70f8a8fe3819dd4265d1ed064899fe6b.png"},9435:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/left-logical-rotation-f0583e0d308391ed199c78ffeddb9ffa.svg"},3967:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/left-logical-shift-8a7457b9b81e57808f65c343bdf0706f.svg"},4916:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/right-logical-shift-f622a1bc8014edbba4e5222fafabb919.svg"},9411:(e,a,n)=>{n.d(a,{A:()=>t});const t=n.p+"assets/images/simple-double-pointer-be5d7f5c690a7a911d9143a94d2f3e7c.svg"}}]); \ No newline at end of file diff --git a/27/assets/js/47922e7d.ee2c15e6.js b/27/assets/js/47922e7d.c4cfe153.js similarity index 66% rename from 27/assets/js/47922e7d.ee2c15e6.js rename to 27/assets/js/47922e7d.c4cfe153.js index 23165a66..fc6929aa 100644 --- a/27/assets/js/47922e7d.ee2c15e6.js +++ b/27/assets/js/47922e7d.c4cfe153.js @@ -1 +1 @@ -"use strict";(self.webpackChunkhardware_software_interface=self.webpackChunkhardware_software_interface||[]).push([[375],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>u});var a=n(6540);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),g=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=g(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=g(n),y=i,u=d["".concat(s,".").concat(y)]||d[y]||m[y]||r;return n?a.createElement(u,l(l({ref:t},p),{},{components:n})):a.createElement(u,l({ref:t},p))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=y;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:i,l[1]=o;for(var g=2;g{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>g});var a=n(8168),i=(n(6540),n(5680));const r={},l="Lab 5 - Introduction to Assembly Language",o={unversionedId:"Labs/lab5",id:"Labs/lab5",title:"Lab 5 - Introduction to Assembly Language",description:"Task: Conditional jumps",source:"@site/docs/Labs/lab5.md",sourceDirName:"Labs",slug:"/Labs/lab5",permalink:"/hardware-software-interface/27/Labs/lab5",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Lab 4 - Toolchain. GOTO",permalink:"/hardware-software-interface/27/Labs/lab4"},next:{title:"Lab 6 - Registers and Memory Addressing",permalink:"/hardware-software-interface/27/Labs/lab6"}},s={},g=[{value:"Task: Conditional jumps",id:"task-conditional-jumps",level:2},{value:"Task: Grumpy Jumps",id:"task-grumpy-jumps",level:2},{value:"Task: Sets",id:"task-sets",level:2},{value:"Task: Min",id:"task-min",level:2},{value:"Task: Fibonacci Sum",id:"task-fibonacci-sum",level:2},{value:"Task: Carry Flag - Overflow Flag",id:"task-carry-flag---overflow-flag",level:2},{value:"Introduction",id:"introduction",level:2},{value:"What is the Assembly Language?",id:"what-is-the-assembly-language",level:3},{value:"Why Learn Assembly Language?",id:"why-learn-assembly-language",level:3},{value:"Debugging",id:"debugging",level:4},{value:"Code Optimization",id:"code-optimization",level:4},{value:"Reverse Engineering",id:"reverse-engineering",level:4},{value:"Embedded and Others",id:"embedded-and-others",level:4},{value:"Fun",id:"fun",level:4},{value:"x86 Family",id:"x86-family",level:2},{value:"Registers",id:"registers",level:3},{value:"Instruction Classes",id:"instruction-classes",level:3},{value:"Data Movement Instructions",id:"data-movement-instructions",level:4},{value:"Arithmetic and Logic Instructions",id:"arithmetic-and-logic-instructions",level:4},{value:"Program Control Instructions",id:"program-control-instructions",level:4},{value:"Guide: First look at Assembly instructions",id:"guide-first-look-at-assembly-instructions",level:2},{value:"Guide: Discovering Assembly",id:"guide-discovering-assembly",level:2}],p={toc:g},d="wrapper";function m(e){let{components:t,...r}=e;return(0,i.yg)(d,(0,a.A)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("h1",{id:"lab-5---introduction-to-assembly-language"},"Lab 5 - Introduction to Assembly Language"),(0,i.yg)("h2",{id:"task-conditional-jumps"},"Task: Conditional jumps"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"hello_world.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/conditional-jumps")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the program so that the message is displayed only if the content of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register is greater than that of ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx"),".\nAlso, modify the values of the registers to continue displaying the message ",(0,i.yg)("inlineCode",{parentName:"p"},'"Hello, World!"'),".")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the program to also display ",(0,i.yg)("inlineCode",{parentName:"p"},'"Goodbye, World!"')," at the end.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Using jump instructions, modify the program to display ",(0,i.yg)("inlineCode",{parentName:"p"},'"Hello, World!"')," N times, where N is given through the ",(0,i.yg)("inlineCode",{parentName:"p"},"ecx")," register.\nAvoid infinite looping."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": After successful completion, the program should display:"),(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-c"},"Hello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nGoodbye, World!\n"))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-grumpy-jumps"},"Task: Grumpy Jumps"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"grumpy_jumps.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/grumpy-jumps")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the values of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers so that when the program is run, the message ",(0,i.yg)("inlineCode",{parentName:"p"},"Well done!")," is displayed.\nFollow the ",(0,i.yg)("inlineCode",{parentName:"p"},"TODO")," comments.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Why does the wrong message still appear?\nModify the source so that the wrong message is not displayed anymore."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": To determine the necessary values for the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers, we recommend using GDB.")),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-sets"},"Task: Sets"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"sets.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/sets")," directory."),(0,i.yg)("p",null,"You need to implement operations on sets that can contain elements between 0 and 31.\nAn efficient way to do this (both in terms of space and speed) would be to represent sets so that a register represents a set.\nEach bit in the register represents an element in the set (if bit i is set, then the set contains element i)."),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": For example: if ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," contains the representation of the set ",(0,i.yg)("inlineCode",{parentName:"p"},"{0,2,4}"),", the register value would be ",(0,i.yg)("inlineCode",{parentName:"p"},"2^0 + 2^2 + 2^4 = 1 + 4 + 16 = 21"),".\nEducate yourself about the available instructions on the ",(0,i.yg)("a",{parentName:"p",href:"guides/x86.html"},"x86 architecture"),".")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"You have two defined sets.\nWhat values do they contain?\nPerform the union of the two sets.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Use the ",(0,i.yg)("inlineCode",{parentName:"p"},"or")," instruction to add two new elements to the set."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),': Take advantage of the fact that the current sets, although they have "space" for 32 bits, only use 8 bits.\nIf you ',(0,i.yg)("inlineCode",{parentName:"p"},"or")," with a number greater than 255 (",(0,i.yg)("inlineCode",{parentName:"p"},"0xff"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"2^8-1"),") which has two active bits, you will effectively add two new elements to the set.")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Perform the intersection of the two sets.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Determine the elements missing from the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," set for it to be complete."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": You need to take the complement of the number using the ",(0,i.yg)("inlineCode",{parentName:"p"},"not")," instruction.")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Remove an element from the first set.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Find the difference between the sets."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": In order to display the answer, you can use the ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," macro.\nFor example:"),(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"PRINTF32 `The union is: \\x0`\nPRINTF32 `%u\\n\\x0`, `EAX`\n"))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-min"},"Task: Min"),(0,i.yg)("p",null,"You will solve this exercise starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"min.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/min")," directory."),(0,i.yg)("p",null,"Calculate the minimum of the numbers in 2 registers (",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx"),") using a comparison instruction, a jump instruction, and the ",(0,i.yg)("inlineCode",{parentName:"p"},"xchg")," instruction."),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-fibonacci-sum"},"Task: Fibonacci Sum"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"fibo_sum.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/fibonacci")," directory.\nStarting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"fibo_sum.asm")," file, implement a program that calculates the sum of the first N numbers in the Fibonacci sequence using the ",(0,i.yg)("inlineCode",{parentName:"p"},"loop")," instruction.\nThe sum of the first 9 numbers is 54."),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab7#structured-data-(structures,-arrays-and-string-operations)"},"this")," reading material."),(0,i.yg)("h2",{id:"task-carry-flag---overflow-flag"},"Task: Carry Flag - Overflow Flag"),(0,i.yg)("p",null,"You will solve this exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"of.asm"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"cf.asm")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"cf_of.asm")," files located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/cf-of")," directory."),(0,i.yg)("p",null,"Using the ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instruction on the ",(0,i.yg)("inlineCode",{parentName:"p"},"al")," register:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set the ",(0,i.yg)("inlineCode",{parentName:"p"},"OF")," flag")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set the ",(0,i.yg)("inlineCode",{parentName:"p"},"CF")," flag")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set both flags simultaneously."))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"introduction"},"Introduction"),(0,i.yg)("p",null,"Before we actually start learning to read code written in assembly language, and then write our first programs, we need to answer a few questions."),(0,i.yg)("h3",{id:"what-is-the-assembly-language"},"What is the Assembly Language?"),(0,i.yg)("p",null,"As you probably know, the basic role of a computer - specifically, of the processor - is to read, interpret, and execute instructions.\nThese instructions are encoded in machine code."),(0,i.yg)("p",null,"An example would be:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"1011000000001100011001100011000111011111111111100100\n")),(0,i.yg)("p",null,"This sequence of bits doesn't tell us much in particular.\nWe can convert it to hexadecimal to compress it and group it better."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"\\xB0\\x0C\\x66\\x31\\xD2\\xFF\\xE4\n")),(0,i.yg)("p",null,"Furthermore, for many of us, this sequence still doesn't mean anything.\nHence the need for a more understandable and usable language."),(0,i.yg)("p",null,"Assembly language allows us to write text programs which will then be translated, through an utility called an ",(0,i.yg)("strong",{parentName:"p"},"assembler"),", specific to each architecture, into machine code.\nMost assembly languages provide a direct correspondence between instructions. For example:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"mov al, 12 <-> '\\xB0\\x0C'\nxor dx, dx <-> '\\x67\\x31\\xD2'\njmp esp <-> '\\xFF\\xE4'\n")),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": Because assembly language depends on architecture, it is generally not portable.\nTherefore, processor manufacturers have tried to keep the instructions unchanged from one generation to another, so that even when adding new processors to the line-up, they would maintain compatibility within the same processor family (for example, Intel processors 80286, 80386, 80486 etc. are all part of the generic Intel x86).")),(0,i.yg)("h3",{id:"why-learn-assembly-language"},"Why Learn Assembly Language?"),(0,i.yg)("p",null,'Besides the very high didactic value, in which you understand what "stack overflow" consists of, data representation, and what is specific to the processor you are working with, there are a few applications where knowledge of assembly language and, implicitly, architecture are necessary or even critical.'),(0,i.yg)("h4",{id:"debugging"},"Debugging"),(0,i.yg)("p",null,"It's quite likely that at least one of the programs you've written in the past generated the following result:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"Segmentation fault\n")),(0,i.yg)("p",null,"Sometimes, you will encounter a series of data similar to the following:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"Page Fault cr2=10000000 at eip e75; flags=6\neax=00000030 ebx=00000000 ecx=0000000c edx=00000000\nesi=0001a44a edi=00000000 ebp=00000000 esp=00002672\ncs=18 ds=38 es=af fs=0 gs=0 ss=20 error=0002\n")),(0,i.yg)("p",null,"For someone who knows assembly language, it's relatively easy to begin troubleshooting using a debugger like ",(0,i.yg)("a",{parentName:"p",href:"http://www.gnu.org/software/gdb/"},"GDB")," or ",(0,i.yg)("a",{parentName:"p",href:"http://www.ollydbg.de/"},"OllyDbg"),", because the message provides almost all the information they need."),(0,i.yg)("h4",{id:"code-optimization"},"Code Optimization"),(0,i.yg)("p",null,'Think about how you would write a C program to perform AES encryption and decryption.\nThen, inform the compiler that you want to optimize your code.\nEvaluate the performance of that code (size, execution time, number of jump instructions, etc.).\nAlthough compilers are often labeled as "black magic", there are situations where you simply know ',(0,i.yg)("a",{parentName:"p",href:"https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf"},"something")," about the processor you're working with better than they do."),(0,i.yg)("p",null,"Furthermore, just understanding assembly code is enough to evaluate a code and optimize its critical sections.\nEven if you don't write code in assembly language, you'll be aware of the code generated from the C instructions you use."),(0,i.yg)("h4",{id:"reverse-engineering"},"Reverse Engineering"),(0,i.yg)("p",null,"A large portion of common applications are closed-source.\nAll you have when it comes to these applications is a pre-compiled binary file.\nSome of these may contain malicious code, in which case they need to be analyzed in a controlled environment (malware analysis/research)."),(0,i.yg)("h4",{id:"embedded-and-others"},"Embedded and Others"),(0,i.yg)("p",null,"There are cases where constraints on code and/or data size are imposed, such as specialized devices for a single task, with little memory.\nThis category includes drivers for devices."),(0,i.yg)("h4",{id:"fun"},"Fun"),(0,i.yg)("p",null,"For more details, discuss with your laboratory assistant to share his personal experience with assembly language and practical use cases."),(0,i.yg)("h2",{id:"x86-family"},"x86 Family"),(0,i.yg)("p",null,"Almost all major processors from Intel share a common ISA (Instruction Set Architecture).\nThese processors are highly backward compatible, with most instructions unchanged over generations, but only added or extended."),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": An ISA defines the instructions supported by a processor, register size, addressing modes, data types, instruction format, interrupts, and memory organization.\nProcessors in this family fall into the broad category of CISC (Complex Instruction Set Computers).\nThe philosophy behind them is to have a large number of instructions, with variable length, capable of performing complex operations, over multiple clock cycles.")),(0,i.yg)("h3",{id:"registers"},"Registers"),(0,i.yg)("p",null,"The basic working units for x86 processors are registers.\nThese are a suite of locations within the processor through which it interacts with memory, I/O, etc."),(0,i.yg)("p",null,"x86 processors have 8 such 32-bit registers.\nAlthough any of these can be used in operations, for historical reasons, each register has a specific role."),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Role"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"eax")),(0,i.yg)("td",{parentName:"tr",align:null},"accumulator; system calls, I/O, arithmetic")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ebx")),(0,i.yg)("td",{parentName:"tr",align:null},"base register; used for memory-based addressing")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ecx")),(0,i.yg)("td",{parentName:"tr",align:null},"counter in loop instructions")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"edx")),(0,i.yg)("td",{parentName:"tr",align:null},"data register, used for I/O, arithmetic, interrupt values; can extend eax to 64 bits")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"esi")),(0,i.yg)("td",{parentName:"tr",align:null},"source in string operations")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"edi")),(0,i.yg)("td",{parentName:"tr",align:null},"destination in string operations")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ebp")),(0,i.yg)("td",{parentName:"tr",align:null},"base or frame pointer; points to the current stack frame")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"esp")),(0,i.yg)("td",{parentName:"tr",align:null},"stack pointer; points to the top of the stack")))),(0,i.yg)("p",null,"In addition to these, there are some special registers that cannot be directly accessed by the programmer, such as ",(0,i.yg)("inlineCode",{parentName:"p"},"eflags")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"eip")," (Instruction Pointer)."),(0,i.yg)("p",null,(0,i.yg)("inlineCode",{parentName:"p"},"eip")," is a register that holds the address of the current instruction to be executed.\nIt cannot be directly modified, programmatically, but indirectly through jump, call, and ret instructions."),(0,i.yg)("p",null,"The ",(0,i.yg)("inlineCode",{parentName:"p"},"eflags")," register contains ",(0,i.yg)("inlineCode",{parentName:"p"},"32")," bits used as status indicators or condition variables.\nWe say that a flag is set if its value is ",(0,i.yg)("inlineCode",{parentName:"p"},"1"),". The ones commonly used by programmers are:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Expanded Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"CF")),(0,i.yg)("td",{parentName:"tr",align:null},"Carry Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result exceeds the maximum (or minimum) unsigned integer value")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"PF")),(0,i.yg)("td",{parentName:"tr",align:null},"Parity Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the low byte of the result contains an even number of 1 bits")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"AF")),(0,i.yg)("td",{parentName:"tr",align:null},"Auxiliary Carry Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Used in BCD arithmetic; set if bit 3 generates a carry or borrow")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ZF")),(0,i.yg)("td",{parentName:"tr",align:null},"Zero Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result of the previous instruction is 0")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"SF")),(0,i.yg)("td",{parentName:"tr",align:null},"Sign Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Has the same value as the sign bit of the result (1 negative, 0 positive)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"OF")),(0,i.yg)("td",{parentName:"tr",align:null},"Overflow Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result exceeds the maximum (or minimum) signed integer value")))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": If you follow the evolution of registers from 8086, you'll see that initially they were named ",(0,i.yg)("inlineCode",{parentName:"p"},"ax"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"bx"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"cx"),' etc., and were 16 bits in size.\nFrom 80386, Intel extended these registers to 32 bits (i.e., "extended" ',(0,i.yg)("inlineCode",{parentName:"p"},"ax")," \u2192 ",(0,i.yg)("inlineCode",{parentName:"p"},"eax"),").")),(0,i.yg)("h3",{id:"instruction-classes"},"Instruction Classes"),(0,i.yg)("p",null,"Although the current set of instructions for Intel processors has ",(0,i.yg)("a",{parentName:"p",href:"https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf"},"hundreds of instructions"),", we will only look at a ",(0,i.yg)("a",{parentName:"p",href:"http://css.csail.mit.edu/6.858/2015/readings/i386.pdf"},"small portion of them"),".\nMore precisely, some of the 80386 instructions."),(0,i.yg)("p",null,"All x86 processors instructions can fit into 3 categories :"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"data movement instructions"),(0,i.yg)("li",{parentName:"ul"},"arithmetical/logical instructions"),(0,i.yg)("li",{parentName:"ul"},"program control instructions")),(0,i.yg)("p",null,"We will only display some of the more important instructions of each category since many of them are alike."),(0,i.yg)("h4",{id:"data-movement-instructions"},"Data Movement Instructions"),(0,i.yg)("p",null,"These instructions are used to transfer data between registers, between memory and registers, and to initialize data:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"mov")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Moves the value from source to the destination(erasing what was in the destination before)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"push")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"src")),(0,i.yg)("td",{parentName:"tr",align:null},'Moves the value from the source onto the "top" of the stack')),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"pop")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst")),(0,i.yg)("td",{parentName:"tr",align:null},'Moves the value from the "top" of the stack into the destination')),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"lea")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Loads the effective address of the source to the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"xchg")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Swaps(Exchanges) the values between the source and the destination")))),(0,i.yg)("h4",{id:"arithmetic-and-logic-instructions"},"Arithmetic and Logic Instructions"),(0,i.yg)("p",null,"These instructions perform arithmetic and logic operations:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"add")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Adds the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"sub")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Subtracts the source from the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"and")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical AND between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"or")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical OR between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"xor")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical XOR between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"test")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical AND between the source and the destination without storing the result")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"shl")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, ")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates the logical shifted value from the destination with a constant number of positions, storing the result in the destination")))),(0,i.yg)("h4",{id:"program-control-instructions"},"Program Control Instructions"),(0,i.yg)("p",null,"These instructions are used to control the flow of programs:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"jmp")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Jumps unconditionally to the specified address(directly, by register, by labels)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"cmp")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Compares the source with the destination(more details below)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},"j",(0,i.yg)("inlineCode",{parentName:"td"},"cond")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Jumps conditionally to the specified address depending on the state of the flag(set/not set)/condition variable")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},"call"),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Calls the subroutine located at the specified address")))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": ",(0,i.yg)("a",{parentName:"p",href:"https://www.felixcloutier.com/x86/cmp"},"The 'cmp dest, src' instruction")," effectively calculates ",(0,i.yg)("inlineCode",{parentName:"p"},"dest - src")," behind the scenes(as in subtracting the source from the destination).\nWe are talking about an unsigned subtraction, without storing the result.")),(0,i.yg)("p",null,"Therefore, when talking about the code:"),(0,i.yg)("blockquote",null,(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"}," cmp eax, 0\n jl negative\n"))),(0,i.yg)("p",null,"The jump to the ",(0,i.yg)("inlineCode",{parentName:"p"},"negative")," label will be made only if the value in eax is less than ",(0,i.yg)("inlineCode",{parentName:"p"},"0"),".\nThe ",(0,i.yg)("inlineCode",{parentName:"p"},"eax - 0")," subtraction is evaluated and if the result is negative(and so, eax is negative), the jump will be made.\\\nWhen have comparisons with ",(0,i.yg)("inlineCode",{parentName:"p"},"0"),", the same thing can be done more efficiently using the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction:"),(0,i.yg)("blockquote",null,(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"}," test eax, eax\n jl negative\n"))),(0,i.yg)("p",null,"More on this ",(0,i.yg)("a",{parentName:"p",href:"https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Comparison_Instructions"},"here"),"."),(0,i.yg)("h2",{id:"guide-first-look-at-assembly-instructions"},"Guide: First look at Assembly instructions"),(0,i.yg)("p",null,"To follow this guide, you will need to use the ",(0,i.yg)("inlineCode",{parentName:"p"},"instructions.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"guides/instructions/support")," directory."),(0,i.yg)("p",null,"Diving right into the demo, we can see one of the most important instructions that helps us, programmers, work with the stack and that is ",(0,i.yg)("inlineCode",{parentName:"p"},"push"),".\nWe discussed what the ",(0,i.yg)("inlineCode",{parentName:"p"},"push")," instruction does in the ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"reading section"),".\nConsidering its call, we can understand that it takes the ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," value(as a ",(0,i.yg)("inlineCode",{parentName:"p"},"DWORD"),", a number stored on ",(0,i.yg)("inlineCode",{parentName:"p"},"4"),' bytes) and moves it onto the "top" of the stack.'),(0,i.yg)("p",null,"That ",(0,i.yg)("inlineCode",{parentName:"p"},"push")," is followed by a new instruction:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"popf\n")),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"IMPORTANT"),": The ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction is used for setting, depending on how many bytes we pop from the stack(in our case, 4 bytes), the ",(0,i.yg)("inlineCode",{parentName:"p"},"EFLAGS")," register(setting the entire register when popping 4 bytes and only the 2 lower bytes of the register when popping 2 bytes).\nYou can read more about the ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction ",(0,i.yg)("a",{parentName:"p",href:"https://www.felixcloutier.com/x86/popf:popfd:popfq"},"here")," and ",(0,i.yg)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/FLAGS_register"},"here"),".")),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"EFLAGS Representation",src:n(7323).A})),(0,i.yg)("p",null,"Having in mind what the ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction does, try to guess what would adding the following line of code at line 15 and the ",(0,i.yg)("inlineCode",{parentName:"p"},"mystery_label")," label at the line(of the current file, before adding the instruction) 53 would make the program do."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"jnc mystery_label\n")),(0,i.yg)("p",null,"Moving on, we can see that the ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," value is set to the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register using the ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," instruction.\nCan you give example of another two ways of setting the value in ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," to ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," without using ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," ?"),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"HINT"),": Think about the ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"logical operators"),".")),(0,i.yg)("p",null,"Next, by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction we can set the ",(0,i.yg)("inlineCode",{parentName:"p"},"flags")," based on the output of the ",(0,i.yg)("inlineCode",{parentName:"p"},"logical and")," between ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and itself."),(0,i.yg)("p",null,"After resetting the flags, we store ",(0,i.yg)("inlineCode",{parentName:"p"},"0xffffffff")," in the ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," register(which is actually the largest number it can store before setting the carry flag) and then use the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction yet again.\nSimilarly, what do you think adding the following line of code after the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction would produce ?"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"jnz mystery_label\n")),(0,i.yg)("p",null,"We reset the flags once again and now we take a look at working with the smaller portions of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register.\nCan you guess the output of the following command, put right under the ",(0,i.yg)("inlineCode",{parentName:"p"},"add al, bl")," instruction ?\nWhat about the flags ?\nWhich flag has been set ?"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"PRINTF32 `%d\\n\\x0`, eax\n")),(0,i.yg)("p",null,"Similarly, try to answer the same questions from above, but considering the next portions of the code."),(0,i.yg)("p",null,"After thoroughly inspecting this example, you should have a vague idea about how setting the flags works."),(0,i.yg)("h2",{id:"guide-discovering-assembly"},"Guide: Discovering Assembly"),(0,i.yg)("p",null,"To follow this guide, you will need to navigate to the ",(0,i.yg)("inlineCode",{parentName:"p"},"guides/discovering-assembly/support")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex1.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, go through the program line by line (the ",(0,i.yg)("inlineCode",{parentName:"p"},"start")," command followed by ",(0,i.yg)("inlineCode",{parentName:"p"},"next"),") and observe the changes in register values after executing the ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instructions.\nIgnore the sequence of ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," instructions.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex2.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, observe the change in the ",(0,i.yg)("inlineCode",{parentName:"p"},"eip")," register when executing the ",(0,i.yg)("inlineCode",{parentName:"p"},"jmp")," instruction.\nTo skip the ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," instructions, add a breakpoint at the ",(0,i.yg)("inlineCode",{parentName:"p"},"jump_incoming")," label (the ",(0,i.yg)("inlineCode",{parentName:"p"},"break")," command followed by ",(0,i.yg)("inlineCode",{parentName:"p"},"run"),").")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex3.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, navigate through the program using breakpoints.\nFollow the program flow.\nWhy is ",(0,i.yg)("inlineCode",{parentName:"p"},"15")," displayed first and then ",(0,i.yg)("inlineCode",{parentName:"p"},"3"),"?\nBecause of the jump at line 9.\nWhere does the jump at line 25 point to?\nTo the ",(0,i.yg)("inlineCode",{parentName:"p"},"zone1")," label.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex4.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, go through the program.\nWhy isn't the jump at line 12 taken?\nBecause the ",(0,i.yg)("inlineCode",{parentName:"p"},"je")," instruction jumps if the ",(0,i.yg)("inlineCode",{parentName:"p"},"ZF")," bit in the ",(0,i.yg)("inlineCode",{parentName:"p"},"FLAGS")," register is set.\nThis bit is set by the ",(0,i.yg)("inlineCode",{parentName:"p"},"cmp")," instruction, which calculates the difference between the values of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers without storing the result.\nHowever, the ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instruction at line 11 clears this flag because the result of the operation is different from 0."))))}m.isMDXComponent=!0},7323:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/eflags-representation-2092cff4e0c5323ca3736ef4a4ab22b4.svg"}}]); \ No newline at end of file +"use strict";(self.webpackChunkhardware_software_interface=self.webpackChunkhardware_software_interface||[]).push([[375],{5680:(e,t,n)=>{n.d(t,{xA:()=>p,yg:()=>u});var a=n(6540);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),g=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=g(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},y=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=g(n),y=i,u=d["".concat(s,".").concat(y)]||d[y]||m[y]||r;return n?a.createElement(u,l(l({ref:t},p),{},{components:n})):a.createElement(u,l({ref:t},p))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=y;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[d]="string"==typeof e?e:i,l[1]=o;for(var g=2;g{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>g});var a=n(8168),i=(n(6540),n(5680));const r={},l="Lab 5 - Introduction to Assembly Language",o={unversionedId:"Labs/lab5",id:"Labs/lab5",title:"Lab 5 - Introduction to Assembly Language",description:"Task: Conditional jumps",source:"@site/docs/Labs/lab5.md",sourceDirName:"Labs",slug:"/Labs/lab5",permalink:"/hardware-software-interface/27/Labs/lab5",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Lab 4 - Toolchain. GOTO",permalink:"/hardware-software-interface/27/Labs/lab4"},next:{title:"Lab 6 - Registers and Memory Addressing",permalink:"/hardware-software-interface/27/Labs/lab6"}},s={},g=[{value:"Task: Conditional jumps",id:"task-conditional-jumps",level:2},{value:"Task: Grumpy Jumps",id:"task-grumpy-jumps",level:2},{value:"Task: Sets",id:"task-sets",level:2},{value:"Task: Min",id:"task-min",level:2},{value:"Task: Fibonacci Sum",id:"task-fibonacci-sum",level:2},{value:"Task: Carry Flag - Overflow Flag",id:"task-carry-flag---overflow-flag",level:2},{value:"Introduction",id:"introduction",level:2},{value:"What is the Assembly Language?",id:"what-is-the-assembly-language",level:3},{value:"Why Learn Assembly Language?",id:"why-learn-assembly-language",level:3},{value:"Debugging",id:"debugging",level:4},{value:"Code Optimization",id:"code-optimization",level:4},{value:"Reverse Engineering",id:"reverse-engineering",level:4},{value:"Embedded and Others",id:"embedded-and-others",level:4},{value:"Fun",id:"fun",level:4},{value:"x86 Family",id:"x86-family",level:2},{value:"Registers",id:"registers",level:3},{value:"Instruction Classes",id:"instruction-classes",level:3},{value:"Data Movement Instructions",id:"data-movement-instructions",level:4},{value:"Arithmetic and Logic Instructions",id:"arithmetic-and-logic-instructions",level:4},{value:"Program Control Instructions",id:"program-control-instructions",level:4},{value:"Guide: First look at Assembly instructions",id:"guide-first-look-at-assembly-instructions",level:2},{value:"Guide: Discovering Assembly",id:"guide-discovering-assembly",level:2}],p={toc:g},d="wrapper";function m(e){let{components:t,...r}=e;return(0,i.yg)(d,(0,a.A)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("h1",{id:"lab-5---introduction-to-assembly-language"},"Lab 5 - Introduction to Assembly Language"),(0,i.yg)("h2",{id:"task-conditional-jumps"},"Task: Conditional jumps"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"hello_world.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/conditional-jumps")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the program so that the message is displayed only if the content of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register is greater than that of ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx"),".\nAlso, modify the values of the registers to continue displaying the message ",(0,i.yg)("inlineCode",{parentName:"p"},'"Hello, World!"'),".")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the program to also display ",(0,i.yg)("inlineCode",{parentName:"p"},'"Goodbye, World!"')," at the end.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Using jump instructions, modify the program to display ",(0,i.yg)("inlineCode",{parentName:"p"},'"Hello, World!"')," N times, where N is given through the ",(0,i.yg)("inlineCode",{parentName:"p"},"ecx")," register.\nAvoid infinite looping."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": After successful completion, the program should display:"),(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-c"},"Hello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\nGoodbye, World!\n"))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-grumpy-jumps"},"Task: Grumpy Jumps"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"grumpy_jumps.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/grumpy-jumps")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Modify the values of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers so that when the program is run, the message ",(0,i.yg)("inlineCode",{parentName:"p"},"Well done!")," is displayed.\nFollow the ",(0,i.yg)("inlineCode",{parentName:"p"},"TODO")," comments.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Why does the wrong message still appear?\nModify the source so that the wrong message is not displayed anymore."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": To determine the necessary values for the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers, we recommend using GDB.")),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-sets"},"Task: Sets"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"sets.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/sets")," directory."),(0,i.yg)("p",null,"You need to implement operations on sets that can contain elements between 0 and 31.\nAn efficient way to do this (both in terms of space and speed) would be to represent sets so that a register represents a set.\nEach bit in the register represents an element in the set (if bit i is set, then the set contains element i)."),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": For example: if ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," contains the representation of the set ",(0,i.yg)("inlineCode",{parentName:"p"},"{0,2,4}"),", the register value would be ",(0,i.yg)("inlineCode",{parentName:"p"},"2^0 + 2^2 + 2^4 = 1 + 4 + 16 = 21"),".\nEducate yourself about the available instructions on the ",(0,i.yg)("a",{parentName:"p",href:"guides/x86.html"},"x86 architecture"),".")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"You have two defined sets.\nWhat values do they contain?\nPerform the union of the two sets.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Use the ",(0,i.yg)("inlineCode",{parentName:"p"},"or")," instruction to add two new elements to the set."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),': Take advantage of the fact that the current sets, although they have "space" for 32 bits, only use 8 bits.\nIf you ',(0,i.yg)("inlineCode",{parentName:"p"},"or")," with a number greater than 255 (",(0,i.yg)("inlineCode",{parentName:"p"},"0xff"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"2^8-1"),") which has two active bits, you will effectively add two new elements to the set.")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Perform the intersection of the two sets.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Determine the elements missing from the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," set for it to be complete."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"TIP"),": You need to take the complement of the number using the ",(0,i.yg)("inlineCode",{parentName:"p"},"not")," instruction.")),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Remove an element from the first set.")),(0,i.yg)("li",{parentName:"ul"},(0,i.yg)("p",{parentName:"li"},"Find the difference between the sets."))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": In order to display the answer, you can use the ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," macro.\nFor example:"),(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"PRINTF32 `The union is: \\x0`\nPRINTF32 `%u\\n\\x0`, `EAX`\n"))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-min"},"Task: Min"),(0,i.yg)("p",null,"You will solve this exercise starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"min.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/min")," directory."),(0,i.yg)("p",null,"Calculate the minimum of the numbers in 2 registers (",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx"),") using a comparison instruction, a jump instruction, and the ",(0,i.yg)("inlineCode",{parentName:"p"},"xchg")," instruction."),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"task-fibonacci-sum"},"Task: Fibonacci Sum"),(0,i.yg)("p",null,"You will solve the exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"fibo_sum.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/fibonacci")," directory.\nStarting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"fibo_sum.asm")," file, implement a program that calculates the sum of the first N numbers in the Fibonacci sequence using the ",(0,i.yg)("inlineCode",{parentName:"p"},"loop")," instruction.\nThe sum of the first 9 numbers is 54."),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab7#structured-data-(structures,-arrays-and-string-operations)"},"this")," reading material."),(0,i.yg)("h2",{id:"task-carry-flag---overflow-flag"},"Task: Carry Flag - Overflow Flag"),(0,i.yg)("p",null,"You will solve this exercises starting from the ",(0,i.yg)("inlineCode",{parentName:"p"},"of.asm"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"cf.asm")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"cf_of.asm")," files located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"drills/tasks/cf-of")," directory."),(0,i.yg)("p",null,"Using the ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instruction on the ",(0,i.yg)("inlineCode",{parentName:"p"},"al")," register:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set the ",(0,i.yg)("inlineCode",{parentName:"p"},"OF")," flag")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set the ",(0,i.yg)("inlineCode",{parentName:"p"},"CF")," flag")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Set both flags simultaneously."))),(0,i.yg)("p",null,"If you're having difficulties solving this exercise, go through ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"this")," reading material."),(0,i.yg)("h2",{id:"introduction"},"Introduction"),(0,i.yg)("p",null,"Before we actually start learning to read code written in assembly language, and then write our first programs, we need to answer a few questions."),(0,i.yg)("h3",{id:"what-is-the-assembly-language"},"What is the Assembly Language?"),(0,i.yg)("p",null,"As you probably know, the basic role of a computer - specifically, of the processor - is to read, interpret, and execute instructions.\nThese instructions are encoded in machine code."),(0,i.yg)("p",null,"An example would be:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"1011000000001100011001100011000111011111111111100100\n")),(0,i.yg)("p",null,"This sequence of bits doesn't tell us much in particular.\nWe can convert it to hexadecimal to compress it and group it better."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"\\xB0\\x0C\\x66\\x31\\xD2\\xFF\\xE4\n")),(0,i.yg)("p",null,"Furthermore, for many of us, this sequence still doesn't mean anything.\nHence the need for a more understandable and usable language."),(0,i.yg)("p",null,"Assembly language allows us to write text programs which will then be translated, through an utility called an ",(0,i.yg)("strong",{parentName:"p"},"assembler"),", specific to each architecture, into machine code.\nMost assembly languages provide a direct correspondence between instructions. For example:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"mov al, 12 <-> '\\xB0\\x0C'\nxor dx, dx <-> '\\x67\\x31\\xD2'\njmp esp <-> '\\xFF\\xE4'\n")),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": Because assembly language depends on architecture, it is generally not portable.\nTherefore, processor manufacturers have tried to keep the instructions unchanged from one generation to another, so that even when adding new processors to the line-up, they would maintain compatibility within the same processor family (for example, Intel processors 80286, 80386, 80486 etc. are all part of the generic Intel x86).")),(0,i.yg)("h3",{id:"why-learn-assembly-language"},"Why Learn Assembly Language?"),(0,i.yg)("p",null,'Besides the very high didactic value, in which you understand what "stack overflow" consists of, data representation, and what is specific to the processor you are working with, there are a few applications where knowledge of assembly language and, implicitly, architecture are necessary or even critical.'),(0,i.yg)("h4",{id:"debugging"},"Debugging"),(0,i.yg)("p",null,"It's quite likely that at least one of the programs you've written in the past generated the following result:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"Segmentation fault\n")),(0,i.yg)("p",null,"Sometimes, you will encounter a series of data similar to the following:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-text"},"Page Fault cr2=10000000 at eip e75; flags=6\neax=00000030 ebx=00000000 ecx=0000000c edx=00000000\nesi=0001a44a edi=00000000 ebp=00000000 esp=00002672\ncs=18 ds=38 es=af fs=0 gs=0 ss=20 error=0002\n")),(0,i.yg)("p",null,"For someone who knows assembly language, it's relatively easy to begin troubleshooting using a debugger like ",(0,i.yg)("a",{parentName:"p",href:"http://www.gnu.org/software/gdb/"},"GDB")," or ",(0,i.yg)("a",{parentName:"p",href:"http://www.ollydbg.de/"},"OllyDbg"),", because the message provides almost all the information they need."),(0,i.yg)("h4",{id:"code-optimization"},"Code Optimization"),(0,i.yg)("p",null,'Think about how you would write a C program to perform AES encryption and decryption.\nThen, inform the compiler that you want to optimize your code.\nEvaluate the performance of that code (size, execution time, number of jump instructions, etc.).\nAlthough compilers are often labeled as "black magic", there are situations where you simply know ',(0,i.yg)("a",{parentName:"p",href:"https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf"},"something")," about the processor you're working with better than they do."),(0,i.yg)("p",null,"Furthermore, just understanding assembly code is enough to evaluate a code and optimize its critical sections.\nEven if you don't write code in assembly language, you'll be aware of the code generated from the C instructions you use."),(0,i.yg)("h4",{id:"reverse-engineering"},"Reverse Engineering"),(0,i.yg)("p",null,"A large portion of common applications are closed-source.\nAll you have when it comes to these applications is a pre-compiled binary file.\nSome of these may contain malicious code, in which case they need to be analyzed in a controlled environment (malware analysis/research)."),(0,i.yg)("h4",{id:"embedded-and-others"},"Embedded and Others"),(0,i.yg)("p",null,"There are cases where constraints on code and/or data size are imposed, such as specialized devices for a single task, with little memory.\nThis category includes drivers for devices."),(0,i.yg)("h4",{id:"fun"},"Fun"),(0,i.yg)("p",null,"For more details, discuss with your laboratory assistant to share his personal experience with assembly language and practical use cases."),(0,i.yg)("h2",{id:"x86-family"},"x86 Family"),(0,i.yg)("p",null,"Almost all major processors from Intel share a common ISA (Instruction Set Architecture).\nThese processors are highly backward compatible, with most instructions unchanged over generations, but only added or extended."),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": An ISA defines the instructions supported by a processor, register size, addressing modes, data types, instruction format, interrupts, and memory organization.\nProcessors in this family fall into the broad category of CISC (Complex Instruction Set Computers).\nThe philosophy behind them is to have a large number of instructions, with variable length, capable of performing complex operations, over multiple clock cycles.")),(0,i.yg)("h3",{id:"registers"},"Registers"),(0,i.yg)("p",null,"The basic working units for x86 processors are registers.\nThese are a suite of locations within the processor through which it interacts with memory, I/O, etc."),(0,i.yg)("p",null,"x86 processors have 8 such 32-bit registers.\nAlthough any of these can be used in operations, for historical reasons, each register has a specific role."),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Role"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"eax")),(0,i.yg)("td",{parentName:"tr",align:null},"accumulator; system calls, I/O, arithmetic")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ebx")),(0,i.yg)("td",{parentName:"tr",align:null},"base register; used for memory-based addressing")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ecx")),(0,i.yg)("td",{parentName:"tr",align:null},"counter in loop instructions")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"edx")),(0,i.yg)("td",{parentName:"tr",align:null},"data register, used for I/O, arithmetic, interrupt values; can extend eax to 64 bits")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"esi")),(0,i.yg)("td",{parentName:"tr",align:null},"source in string operations")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"edi")),(0,i.yg)("td",{parentName:"tr",align:null},"destination in string operations")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ebp")),(0,i.yg)("td",{parentName:"tr",align:null},"base or frame pointer; points to the current stack frame")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"esp")),(0,i.yg)("td",{parentName:"tr",align:null},"stack pointer; points to the top of the stack")))),(0,i.yg)("p",null,"In addition to these, there are some special registers that cannot be directly accessed by the programmer, such as ",(0,i.yg)("inlineCode",{parentName:"p"},"eflags")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"eip")," (Instruction Pointer)."),(0,i.yg)("p",null,(0,i.yg)("inlineCode",{parentName:"p"},"eip")," is a register that holds the address of the current instruction to be executed.\nIt cannot be directly modified, programmatically, but indirectly through jump, call, and ret instructions."),(0,i.yg)("p",null,"The ",(0,i.yg)("inlineCode",{parentName:"p"},"eflags")," register contains ",(0,i.yg)("inlineCode",{parentName:"p"},"32")," bits used as status indicators or condition variables.\nWe say that a flag is set if its value is ",(0,i.yg)("inlineCode",{parentName:"p"},"1"),". The ones commonly used by programmers are:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Expanded Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"CF")),(0,i.yg)("td",{parentName:"tr",align:null},"Carry Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result exceeds the maximum (or minimum) unsigned integer value")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"PF")),(0,i.yg)("td",{parentName:"tr",align:null},"Parity Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the low byte of the result contains an even number of 1 bits")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"AF")),(0,i.yg)("td",{parentName:"tr",align:null},"Auxiliary Carry Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Used in BCD arithmetic; set if bit 3 generates a carry or borrow")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"ZF")),(0,i.yg)("td",{parentName:"tr",align:null},"Zero Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result of the previous instruction is 0")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"SF")),(0,i.yg)("td",{parentName:"tr",align:null},"Sign Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Has the same value as the sign bit of the result (1 negative, 0 positive)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"OF")),(0,i.yg)("td",{parentName:"tr",align:null},"Overflow Flag"),(0,i.yg)("td",{parentName:"tr",align:null},"Set if the result exceeds the maximum (or minimum) signed integer value")))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": If you follow the evolution of registers from 8086, you'll see that initially they were named ",(0,i.yg)("inlineCode",{parentName:"p"},"ax"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"bx"),", ",(0,i.yg)("inlineCode",{parentName:"p"},"cx"),' etc., and were 16 bits in size.\nFrom 80386, Intel extended these registers to 32 bits (i.e., "extended" ',(0,i.yg)("inlineCode",{parentName:"p"},"ax")," \u2192 ",(0,i.yg)("inlineCode",{parentName:"p"},"eax"),").")),(0,i.yg)("h3",{id:"instruction-classes"},"Instruction Classes"),(0,i.yg)("p",null,"Although the current set of instructions for Intel processors has ",(0,i.yg)("a",{parentName:"p",href:"https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf"},"hundreds of instructions"),", we will only look at a ",(0,i.yg)("a",{parentName:"p",href:"http://css.csail.mit.edu/6.858/2015/readings/i386.pdf"},"small portion of them"),".\nMore precisely, some of the 80386 instructions."),(0,i.yg)("p",null,"All x86 processors instructions can fit into 3 categories :"),(0,i.yg)("ul",null,(0,i.yg)("li",{parentName:"ul"},"data movement instructions"),(0,i.yg)("li",{parentName:"ul"},"arithmetical/logical instructions"),(0,i.yg)("li",{parentName:"ul"},"program control instructions")),(0,i.yg)("p",null,"We will only display some of the more important instructions of each category since many of them are alike."),(0,i.yg)("h4",{id:"data-movement-instructions"},"Data Movement Instructions"),(0,i.yg)("p",null,"These instructions are used to transfer data between registers, between memory and registers, and to initialize data:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"mov")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Moves the value from source to the destination(erasing what was in the destination before)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"push")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"src")),(0,i.yg)("td",{parentName:"tr",align:null},'Moves the value from the source onto the "top" of the stack')),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"pop")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst")),(0,i.yg)("td",{parentName:"tr",align:null},'Moves the value from the "top" of the stack into the destination')),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"lea")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Loads the effective address of the source to the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"xchg")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Swaps (Exchanges) the values between the source and the destination")))),(0,i.yg)("h4",{id:"arithmetic-and-logic-instructions"},"Arithmetic and Logic Instructions"),(0,i.yg)("p",null,"These instructions perform arithmetic and logic operations:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"add")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Adds the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"sub")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Subtracts the source from the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"and")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical AND between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"or")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical OR between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"xor")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical XOR between the source and the destination, storing the result in the destination")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"test")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates logical AND between the source and the destination without storing the result")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"shl")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, ")),(0,i.yg)("td",{parentName:"tr",align:null},"Calculates the logical shifted value from the destination with a constant number of positions, storing the result in the destination")))),(0,i.yg)("h4",{id:"program-control-instructions"},"Program Control Instructions"),(0,i.yg)("p",null,"These instructions are used to control the flow of programs:"),(0,i.yg)("table",null,(0,i.yg)("thead",{parentName:"table"},(0,i.yg)("tr",{parentName:"thead"},(0,i.yg)("th",{parentName:"tr",align:null},"Name"),(0,i.yg)("th",{parentName:"tr",align:null},"Operands"),(0,i.yg)("th",{parentName:"tr",align:null},"Description"))),(0,i.yg)("tbody",{parentName:"table"},(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"jmp")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Jumps unconditionally to the specified address(directly, by register, by labels)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"cmp")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"dst, src")),(0,i.yg)("td",{parentName:"tr",align:null},"Compares the source with the destination(more details below)")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},"j",(0,i.yg)("inlineCode",{parentName:"td"},"cond")),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Jumps conditionally to the specified address depending on the state of the flag(set/not set)/condition variable")),(0,i.yg)("tr",{parentName:"tbody"},(0,i.yg)("td",{parentName:"tr",align:null},"call"),(0,i.yg)("td",{parentName:"tr",align:null},(0,i.yg)("inlineCode",{parentName:"td"},"
")),(0,i.yg)("td",{parentName:"tr",align:null},"Calls the subroutine located at the specified address")))),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"NOTE"),": ",(0,i.yg)("a",{parentName:"p",href:"https://www.felixcloutier.com/x86/cmp"},"The 'cmp dest, src' instruction")," effectively calculates ",(0,i.yg)("inlineCode",{parentName:"p"},"dest - src")," behind the scenes(as in subtracting the source from the destination).\nWe are talking about an unsigned subtraction, without storing the result.")),(0,i.yg)("p",null,"Therefore, when talking about the code:"),(0,i.yg)("blockquote",null,(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"}," cmp eax, 0\n jl negative\n"))),(0,i.yg)("p",null,"The jump to the ",(0,i.yg)("inlineCode",{parentName:"p"},"negative")," label will be made only if the value in eax is less than ",(0,i.yg)("inlineCode",{parentName:"p"},"0"),".\nThe ",(0,i.yg)("inlineCode",{parentName:"p"},"eax - 0")," subtraction is evaluated and if the result is negative(and so, eax is negative), the jump will be made.\\\nWhen have comparisons with ",(0,i.yg)("inlineCode",{parentName:"p"},"0"),", the same thing can be done more efficiently using the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction:"),(0,i.yg)("blockquote",null,(0,i.yg)("pre",{parentName:"blockquote"},(0,i.yg)("code",{parentName:"pre",className:"language-assembly"}," test eax, eax\n jl negative\n"))),(0,i.yg)("p",null,"More on this ",(0,i.yg)("a",{parentName:"p",href:"https://en.wikibooks.org/wiki/X86_Assembly/Control_Flow#Comparison_Instructions"},"here"),"."),(0,i.yg)("h2",{id:"guide-first-look-at-assembly-instructions"},"Guide: First look at Assembly instructions"),(0,i.yg)("p",null,"To follow this guide, you will need to use the ",(0,i.yg)("inlineCode",{parentName:"p"},"instructions.asm")," file located in the ",(0,i.yg)("inlineCode",{parentName:"p"},"guides/instructions/support")," directory."),(0,i.yg)("p",null,"Diving right into the demo, we can see one of the most important instructions that helps us, programmers, work with the stack and that is ",(0,i.yg)("inlineCode",{parentName:"p"},"push"),".\nWe discussed what the ",(0,i.yg)("inlineCode",{parentName:"p"},"push")," instruction does in the ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"reading section"),".\nConsidering its call, we can understand that it takes the ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," value(as a ",(0,i.yg)("inlineCode",{parentName:"p"},"DWORD"),", a number stored on ",(0,i.yg)("inlineCode",{parentName:"p"},"4"),' bytes) and moves it onto the "top" of the stack.'),(0,i.yg)("p",null,"That ",(0,i.yg)("inlineCode",{parentName:"p"},"push")," is followed by a new instruction:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"popf\n")),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"IMPORTANT"),": The ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction is used for setting, depending on how many bytes we pop from the stack(in our case, 4 bytes), the ",(0,i.yg)("inlineCode",{parentName:"p"},"EFLAGS")," register(setting the entire register when popping 4 bytes and only the 2 lower bytes of the register when popping 2 bytes).\nYou can read more about the ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction ",(0,i.yg)("a",{parentName:"p",href:"https://www.felixcloutier.com/x86/popf:popfd:popfq"},"here")," and ",(0,i.yg)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/FLAGS_register"},"here"),".")),(0,i.yg)("p",null,(0,i.yg)("img",{alt:"EFLAGS Representation",src:n(7323).A})),(0,i.yg)("p",null,"Having in mind what the ",(0,i.yg)("inlineCode",{parentName:"p"},"popf")," instruction does, try to guess what would adding the following line of code at line 15 and the ",(0,i.yg)("inlineCode",{parentName:"p"},"mystery_label")," label at the line(of the current file, before adding the instruction) 53 would make the program do."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"jnc mystery_label\n")),(0,i.yg)("p",null,"Moving on, we can see that the ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," value is set to the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register using the ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," instruction.\nCan you give example of another two ways of setting the value in ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," to ",(0,i.yg)("inlineCode",{parentName:"p"},"0")," without using ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," ?"),(0,i.yg)("blockquote",null,(0,i.yg)("p",{parentName:"blockquote"},(0,i.yg)("strong",{parentName:"p"},"HINT"),": Think about the ",(0,i.yg)("a",{parentName:"p",href:"/hardware-software-interface/27/Labs/lab5#x86-family"},"logical operators"),".")),(0,i.yg)("p",null,"Next, by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction we can set the ",(0,i.yg)("inlineCode",{parentName:"p"},"flags")," based on the output of the ",(0,i.yg)("inlineCode",{parentName:"p"},"logical and")," between ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and itself."),(0,i.yg)("p",null,"After resetting the flags, we store ",(0,i.yg)("inlineCode",{parentName:"p"},"0xffffffff")," in the ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," register(which is actually the largest number it can store before setting the carry flag) and then use the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction yet again.\nSimilarly, what do you think adding the following line of code after the ",(0,i.yg)("inlineCode",{parentName:"p"},"test")," instruction would produce ?"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"jnz mystery_label\n")),(0,i.yg)("p",null,"We reset the flags once again and now we take a look at working with the smaller portions of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," register.\nCan you guess the output of the following command, put right under the ",(0,i.yg)("inlineCode",{parentName:"p"},"add al, bl")," instruction ?\nWhat about the flags ?\nWhich flag has been set ?"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-assembly"},"PRINTF32 `%d\\n\\x0`, eax\n")),(0,i.yg)("p",null,"Similarly, try to answer the same questions from above, but considering the next portions of the code."),(0,i.yg)("p",null,"After thoroughly inspecting this example, you should have a vague idea about how setting the flags works."),(0,i.yg)("h2",{id:"guide-discovering-assembly"},"Guide: Discovering Assembly"),(0,i.yg)("p",null,"To follow this guide, you will need to navigate to the ",(0,i.yg)("inlineCode",{parentName:"p"},"guides/discovering-assembly/support")," directory."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex1.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, go through the program line by line (the ",(0,i.yg)("inlineCode",{parentName:"p"},"start")," command followed by ",(0,i.yg)("inlineCode",{parentName:"p"},"next"),") and observe the changes in register values after executing the ",(0,i.yg)("inlineCode",{parentName:"p"},"mov")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instructions.\nIgnore the sequence of ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," instructions.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex2.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, observe the change in the ",(0,i.yg)("inlineCode",{parentName:"p"},"eip")," register when executing the ",(0,i.yg)("inlineCode",{parentName:"p"},"jmp")," instruction.\nTo skip the ",(0,i.yg)("inlineCode",{parentName:"p"},"PRINTF32")," instructions, add a breakpoint at the ",(0,i.yg)("inlineCode",{parentName:"p"},"jump_incoming")," label (the ",(0,i.yg)("inlineCode",{parentName:"p"},"break")," command followed by ",(0,i.yg)("inlineCode",{parentName:"p"},"run"),").")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex3.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, navigate through the program using breakpoints.\nFollow the program flow.\nWhy is ",(0,i.yg)("inlineCode",{parentName:"p"},"15")," displayed first and then ",(0,i.yg)("inlineCode",{parentName:"p"},"3"),"?\nBecause of the jump at line 9.\nWhere does the jump at line 25 point to?\nTo the ",(0,i.yg)("inlineCode",{parentName:"p"},"zone1")," label.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Open the ",(0,i.yg)("inlineCode",{parentName:"p"},"ex4.asm")," file and read the comments.\nAssemble it by using the ",(0,i.yg)("inlineCode",{parentName:"p"},"make")," utility and run it.\nUsing gdb, go through the program.\nWhy isn't the jump at line 12 taken?\nBecause the ",(0,i.yg)("inlineCode",{parentName:"p"},"je")," instruction jumps if the ",(0,i.yg)("inlineCode",{parentName:"p"},"ZF")," bit in the ",(0,i.yg)("inlineCode",{parentName:"p"},"FLAGS")," register is set.\nThis bit is set by the ",(0,i.yg)("inlineCode",{parentName:"p"},"cmp")," instruction, which calculates the difference between the values of the ",(0,i.yg)("inlineCode",{parentName:"p"},"eax")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"ebx")," registers without storing the result.\nHowever, the ",(0,i.yg)("inlineCode",{parentName:"p"},"add")," instruction at line 11 clears this flag because the result of the operation is different from 0."))))}m.isMDXComponent=!0},7323:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/eflags-representation-2092cff4e0c5323ca3736ef4a4ab22b4.svg"}}]); \ No newline at end of file diff --git a/27/assets/js/runtime~main.af9036cb.js b/27/assets/js/runtime~main.be82e177.js similarity index 51% rename from 27/assets/js/runtime~main.af9036cb.js rename to 27/assets/js/runtime~main.be82e177.js index fb0bad5a..0ad28e65 100644 --- a/27/assets/js/runtime~main.af9036cb.js +++ b/27/assets/js/runtime~main.be82e177.js @@ -1 +1 @@ -(()=>{"use strict";var e,r,t,a,o,f={},n={};function i(e){var r=n[e];if(void 0!==r)return r.exports;var t=n[e]={id:e,loaded:!1,exports:{}};return f[e].call(t.exports,t,t.exports,i),t.loaded=!0,t.exports}i.m=f,i.c=n,e=[],i.O=(r,t,a,o)=>{if(!t){var f=1/0;for(u=0;u=o)&&Object.keys(i.O).every((e=>i.O[e](t[d])))?t.splice(d--,1):(n=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[t,a,o]},i.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return i.d(r,{a:r}),r},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,i.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);i.r(o);var f={};r=r||[null,t({}),t([]),t(t)];for(var n=2&a&&e;"object"==typeof n&&!~r.indexOf(n);n=t(n))Object.getOwnPropertyNames(n).forEach((r=>f[r]=()=>e[r]));return f.default=()=>e,i.d(o,f),o},i.d=(e,r)=>{for(var t in r)i.o(r,t)&&!i.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},i.f={},i.e=e=>Promise.all(Object.keys(i.f).reduce(((r,t)=>(i.f[t](e,r),r)),[])),i.u=e=>"assets/js/"+({61:"1f391b9e",93:"84585675",134:"393be207",348:"137b52b7",375:"47922e7d",376:"e81f7e3d",401:"17896441",432:"eb6a5da1",442:"fc32d178",461:"530f01d5",581:"935f2afb",658:"79ca8b47",714:"1be78505",729:"445f73da",767:"7801b8ae",874:"04860bfc",969:"14eb3368"}[e]||e)+"."+{61:"a3454229",93:"e1d34827",134:"1d542f24",348:"ff676f8b",375:"ee2c15e6",376:"b714acd7",401:"d90e9b51",432:"fb7bad11",442:"ae5131b5",461:"81e06f99",567:"650c4729",581:"3e12a31c",658:"62367b79",714:"1619529a",729:"c655cbc8",767:"9a07ce05",774:"a904d6fb",874:"4501aac3",969:"f34adf59"}[e]+".js",i.miniCssF=e=>{},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),a={},o="hardware-software-interface:",i.l=(e,r,t,f)=>{if(a[e])a[e].push(r);else{var n,d;if(void 0!==t)for(var c=document.getElementsByTagName("script"),u=0;u{n.onerror=n.onload=null,clearTimeout(s);var o=a[e];if(delete a[e],n.parentNode&&n.parentNode.removeChild(n),o&&o.forEach((e=>e(t))),r)return r(t)},s=setTimeout(b.bind(null,void 0,{type:"timeout",target:n}),12e4);n.onerror=b.bind(null,n.onerror),n.onload=b.bind(null,n.onload),d&&document.head.appendChild(n)}},i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.p="/hardware-software-interface/27/",i.gca=function(e){return e={17896441:"401",84585675:"93","1f391b9e":"61","393be207":"134","137b52b7":"348","47922e7d":"375",e81f7e3d:"376",eb6a5da1:"432",fc32d178:"442","530f01d5":"461","935f2afb":"581","79ca8b47":"658","1be78505":"714","445f73da":"729","7801b8ae":"767","04860bfc":"874","14eb3368":"969"}[e]||e,i.p+i.u(e)},(()=>{var e={354:0,869:0};i.f.j=(r,t)=>{var a=i.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(/^(354|869)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>a=e[r]=[t,o]));t.push(a[2]=o);var f=i.p+i.u(r),n=new Error;i.l(f,(t=>{if(i.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),f=t&&t.target&&t.target.src;n.message="Loading chunk "+r+" failed.\n("+o+": "+f+")",n.name="ChunkLoadError",n.type=o,n.request=f,a[1](n)}}),"chunk-"+r,r)}},i.O.j=r=>0===e[r];var r=(r,t)=>{var a,o,f=t[0],n=t[1],d=t[2],c=0;if(f.some((r=>0!==e[r]))){for(a in n)i.o(n,a)&&(i.m[a]=n[a]);if(d)var u=d(i)}for(r&&r(t);c{"use strict";var e,r,t,a,o,n={},f={};function i(e){var r=f[e];if(void 0!==r)return r.exports;var t=f[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,i),t.loaded=!0,t.exports}i.m=n,i.c=f,e=[],i.O=(r,t,a,o)=>{if(!t){var n=1/0;for(u=0;u=o)&&Object.keys(i.O).every((e=>i.O[e](t[c])))?t.splice(c--,1):(f=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[t,a,o]},i.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return i.d(r,{a:r}),r},t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,i.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);i.r(o);var n={};r=r||[null,t({}),t([]),t(t)];for(var f=2&a&&e;"object"==typeof f&&!~r.indexOf(f);f=t(f))Object.getOwnPropertyNames(f).forEach((r=>n[r]=()=>e[r]));return n.default=()=>e,i.d(o,n),o},i.d=(e,r)=>{for(var t in r)i.o(r,t)&&!i.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},i.f={},i.e=e=>Promise.all(Object.keys(i.f).reduce(((r,t)=>(i.f[t](e,r),r)),[])),i.u=e=>"assets/js/"+({61:"1f391b9e",93:"84585675",134:"393be207",348:"137b52b7",375:"47922e7d",376:"e81f7e3d",401:"17896441",432:"eb6a5da1",442:"fc32d178",461:"530f01d5",581:"935f2afb",658:"79ca8b47",714:"1be78505",729:"445f73da",767:"7801b8ae",874:"04860bfc",969:"14eb3368"}[e]||e)+"."+{61:"a3454229",93:"e1d34827",134:"1d542f24",348:"dcf58f32",375:"c4cfe153",376:"b714acd7",401:"d90e9b51",432:"fb7bad11",442:"ae5131b5",461:"81e06f99",567:"650c4729",581:"3e12a31c",658:"62367b79",714:"1619529a",729:"c655cbc8",767:"9a07ce05",774:"a904d6fb",874:"4501aac3",969:"f34adf59"}[e]+".js",i.miniCssF=e=>{},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),a={},o="hardware-software-interface:",i.l=(e,r,t,n)=>{if(a[e])a[e].push(r);else{var f,c;if(void 0!==t)for(var d=document.getElementsByTagName("script"),u=0;u{f.onerror=f.onload=null,clearTimeout(b);var o=a[e];if(delete a[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(t))),r)return r(t)},b=setTimeout(s.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=s.bind(null,f.onerror),f.onload=s.bind(null,f.onload),c&&document.head.appendChild(f)}},i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.p="/hardware-software-interface/27/",i.gca=function(e){return e={17896441:"401",84585675:"93","1f391b9e":"61","393be207":"134","137b52b7":"348","47922e7d":"375",e81f7e3d:"376",eb6a5da1:"432",fc32d178:"442","530f01d5":"461","935f2afb":"581","79ca8b47":"658","1be78505":"714","445f73da":"729","7801b8ae":"767","04860bfc":"874","14eb3368":"969"}[e]||e,i.p+i.u(e)},(()=>{var e={354:0,869:0};i.f.j=(r,t)=>{var a=i.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(/^(354|869)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>a=e[r]=[t,o]));t.push(a[2]=o);var n=i.p+i.u(r),f=new Error;i.l(n,(t=>{if(i.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;f.message="Loading chunk "+r+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,a[1](f)}}),"chunk-"+r,r)}},i.O.j=r=>0===e[r];var r=(r,t)=>{var a,o,n=t[0],f=t[1],c=t[2],d=0;if(n.some((r=>0!==e[r]))){for(a in f)i.o(f,a)&&(i.m[a]=f[a]);if(c)var u=c(i)}for(r&&r(t);d Introduction | Hardware Software Interface - + @@ -14,7 +14,7 @@ It is meant to be used by teachers, trainers, students and hobbyists who want to learn about topics on calculus and statistics.

The course is structured in chapters, each with their own sections. See chapters in the sidebar or in the top-level menu.

Licensing and Contributing

The contents are open educational resources (OER), part of the Open Education Hub project; they are hosted on GitHub, licensed under CC BY-SA 4.0 and BSD 3-Clause.

If you find an issue or want to contribute, follow the contribution guidelines on GitHub.

- + \ No newline at end of file diff --git a/27/markdown-page/index.html b/27/markdown-page/index.html index 6a100bee..415c5b69 100644 --- a/27/markdown-page/index.html +++ b/27/markdown-page/index.html @@ -4,13 +4,13 @@ Markdown page example | Hardware Software Interface - +

Markdown page example

You don't need React to write simple standalone pages.

- + \ No newline at end of file