You should be able to:

- Be able to convert between binary, hex, and decimal values. Counting on your fingers is encouraged!
- Be able to do arithmetic on binary or hex numbers.
- Understand the sign bit, and the difference in range between signed and unsigned values.

- Bitwise operators:
- &, bitwise and, outputs one bits only when both input bits
are one. 0xff00&0x0ff0 = 0x0f00. Useful for "masking" out
bits you don't want, by and'ing with zeros.

- |, bitwise or, outputs one bits when either input bit is one. 0xff00 | 0x0ff0 = 0xfff0.
- ^, bitwise xor, outputs one bits when either input bit is one, but not both. 0xff00 | 0x0ff0 = 0x0ff0.
- <<, left shift, makes values bigger. "shl" in
assembly. 1<<n is a 1 followed by n zeros in binary, so
1<<n == 2
^{n}, k<<n == k*2^{n}. 0xf0 << 4 == 0xf00.

- >>, right shift, makes values smaller. "shr" (unsigned) or "sar" (signed) in assembly. k>>n == k/2
^{n}^{}. 0xf0 >> 4 == 0xf. - ~, bitwise not, inverts all the bits. ~0 is all-ones (0xffFFffFF, or -1).

- Number of bits in a hex digit: 4. Number of bits in a byte: 8. Number of bits per C++ datatype on a 32-bit machine:

bits in a char: 8

bits in a short: 16

bits in an int: 32

bits in a long: 32

bits in a long long: 64

bits in a pointer: 32template <class TYPE>

int count_bits(TYPE t) {

int n_bits=0;

while (t!=0) {

t=t+t; /* double the type value */

n_bits++;

}

return n_bits;

}

int foo(void) {

std::cout<<" bits in a char: "<< count_bits((char)1) <<"\n";

std::cout<<" bits in a short: "<< count_bits((short)1) <<"\n";

std::cout<<" bits in an int: "<< count_bits((int)1) <<"\n";

std::cout<<" bits in a long: "<< count_bits((long)1) <<"\n";

std::cout<<" bits in a long long: "<< count_bits((long long)1) <<"\n";

//std::cout<<" bits in a pointer: "<< count_bits((char *)1) <<"\n";

return 0;

} - Understand the concept behind machine code.
- Know which registers exist, and which you can freely trash (just
eax, ecx, and edx) versus those you must save and restore (esp, ebp,
esi, edi, ebx).

- Be able to write "if", "while", and "for" loops in assembly, using "cmp" and j-something instructions (like "jle").
- Be able to allocate and free memory on the stack (add and sub the stack pointer) and heap (malloc and free), and know the difference between them.
- Know what the memory looks like for:
- An integer: little endian storage gives the first, lowest-address byte the lowest value.

- An array: [0] is the first element, at the array start pointer. [1] is 4 bytes higher (for an int array). [i] is 4*i bytes from the array start, like DWORD[esp+4*ecx].
- A class/struct: the members of the class, one after another. Only weird part is "padding", needed for alignment.

- Your function parameters: they're passed on the stack, just deeper than your function's return address. DWORD[esp+4] is your first argument.
- Before, during, and after a function call and return.
- Use all of the above to translate into assembly language simple
C++ programs involving arithmetic, array accesses, branches, loops, and
function calls.