Info

Übungen

#timestamp 20250917

install work enviroment on Linux Arch/Manjaro:

sudo pacman -S base-devel flex bison

bitwise operations -> 10% of exam!


common bitwise functions:

// check equality
return !(x^y);
// negative number
return ~x + 1;
// min two's complement (32bit)
return 1 << 31;
// bitwise not on 0:
// because ~0 = ~000000 = 111111 = -1
~0 = -1

#timestamp 2025-09-24

Avoid including the same file multiple times with header guards:

#ifndef HEADER_FILE
#define HEADER_FILE

// the entire header file

# endif // HEADER_FILE

system include files can be found in /usr/include

#timestamp 2025-10-22

cmpq %rax, %rbx
jg X

=> jumps if %rbx > %rax

Pasted image 20251022231913.png

for callee-saved: one needs to restore value after using

pushq %r12       # save original value
...
popq %r12        # restore original value

inline assembly:

int a=10, b;
__asm__ ("movl %1, %%eax; movl %%eax, %0;"
		:"=r"(b) // output operands, optional
		:"r"(a)  // input operands, optional
		:"%eax"  // list of clobbered registers, optional
);

or named:

int a=10, b;
__asm__ ("movl %[in], %%eax; movl %%eax, %[out];"
		: [out] "=r"(b) // output operands, optional
		: [in]  "r"(a)  // input operands, optional
		:"%eax"  // list of clobbered registers, optional
);

of course, it can be simplified:

int a=10, b;
__asm__ ("movl %[in], %[out]"
		: [out] "=r"(b) // output operands, optional
		: [in]  "r"(a)  // input operands, optional
);

if no variable changes, use volatile to prevent the compile from deleting it!

__asm__ volatile ("movb %bh (%eax)\n\t"); // \n\t for multiple instructions needed, here optional

#timestamp 2025-11-05

symbols

-> modern C: always mark extern (and -fno-common flag) s.t. there is no arbitrary choosing

libraries

static libraries (.a)

dynamic libraries
Pasted image 20251105144714.png


append library path:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD

32-bit PC-relative displacement

A 4-byte signed number stored in the instruction that tells the CPU how many bytes to jump forward/backwards from the next instruction. (PC = Program Counter = %rip on x86)

e.g.

400406: e8 f5 00 00 00 callq 400500 <swap>

CPU doesn't know the symbol name (swap), it only sees the displacement

This comes from how the program is created:

  1. the compiler doesn't know swap's final address -> writes instruction + placeholder, e.g. e8 00 00 00 00 and adds a relocation entry
  2. the linker assigns final addresses to all functions, computes displacement:
    • displacement = next_address (%rip) - next_instruction_address
  3. the CPU executes callq at 0x400406, reads displacement, jumps to right place
  4. disassembly: objump read instruction, computes target address and names after the symbol table ->
    • callq 400500 <swap>

#timestamp 2025-11-26