Q1. What Does This Assembly Addition Code Do?

This assembly code represents the C operation result = left + right by loading left and right from stack memory into CPU registers, adding them with addl, and storing the sum back into the stack slot for result.

More specifically, it loads two int values from the current function’s stack frame, adds them in CPU registers, and stores the result back into another stack slot.

movl    -20(%rbp), %edx
movl    -24(%rbp), %eax
addl    %edx, %eax
movl    %eax, -4(%rbp)

At the C source level, this corresponds to the core operation:

int result = left + right;

The important point is not that every C line always becomes these exact assembly instructions. The important point is that a source-level expression such as left + right is represented at a lower level as memory loads, register operations, and memory stores.

Q2. What Does movl -20(%rbp), %edx Mean?

movl    -20(%rbp), %edx

This instruction copies a 32-bit value from memory into the %edx register.

-20(%rbp) means:

the memory location 20 bytes below the address currently stored in %rbp

In this example, that stack location represents the C parameter left.

So the instruction can be read conceptually as:

%edx = left

This does not mean that C has a variable named %edx. %edx is a CPU register chosen by the compiler as a temporary place to hold the value while the calculation is performed.

Q3. What Does movl -24(%rbp), %eax Mean?

movl    -24(%rbp), %eax

This instruction copies another 32-bit value from memory into the %eax register.

In this example, -24(%rbp) represents the C parameter right.

Conceptually, this instruction means:

%eax = right

Now the two input values are in registers:

%edx = left
%eax = right

Q4. What Does addl %edx, %eax Mean?

addl    %edx, %eax

This instruction adds the value in %edx to the value in %eax, then stores the result in %eax.

In AT&T assembly syntax, the source operand comes first and the destination operand comes second.

So this instruction means:

%eax = %eax + %edx

Given the previous instructions:

%edx = left
%eax = right

the result becomes:

%eax = right + left

Because integer addition is commutative, this represents the same source-level operation as:

left + right

Q5. What Does movl %eax, -4(%rbp) Mean?

movl    %eax, -4(%rbp)

This instruction copies the 32-bit value in %eax back into memory.

In this example, -4(%rbp) represents the local variable result.

So after the addition, the value in %eax is stored into the stack slot for result.

Conceptually:

result = %eax

Since %eax contains the sum, this completes the source-level operation:

int result = left + right;

Q6. Why Are Registers Used Instead of Adding Memory Values Directly?

The CPU usually performs arithmetic through registers.

The general pattern is:

load values from memory
-> place them in registers
-> perform the arithmetic operation in registers
-> store the result back to memory if needed

In this example:

left   is loaded from the stack into %edx
right  is loaded from the stack into %eax
%edx   is added to %eax
%eax   is stored back into the stack slot for result

Registers are small, fast storage locations inside the CPU. Stack slots are memory locations used by the current function. The compiler moves values between stack memory and registers so the CPU can perform the calculation.

Q7. What Is %rbp Doing Here?

%rbp is being used as the base pointer for the current function’s stack frame.

A stack frame is the area of stack memory used by a function call. It can contain saved state, parameters copied by the compiler, local variables, and temporary values.

In this example, offsets from %rbp identify stack locations:

-20(%rbp)  represents left
-24(%rbp)  represents right
-4(%rbp)   represents result

These names do not exist directly in the assembly code. The C variable names are source-level concepts. At the assembly level, the compiler represents them using registers and memory addresses.

Q8. Does int left = 5 Mean left Is Always Stored At -20(%rbp)?

No. left does not inherently mean -20(%rbp).

At the C source level, int left = 5; only says that an int variable named left is initialized with the value 5. It does not specify where that value must live in machine-level storage.

The compiler decides how to represent that variable in the generated code. It may store the value in a stack slot such as -20(%rbp), keep it in a register, or remove the separate variable storage entirely if optimization can treat the value as a constant.

So the accurate reading is not:

left is always -20(%rbp)

The accurate reading is:

in this compiled output, the compiler chose a particular storage location to represent the value associated with left

Q9. What Is The Difference Between A Stack Offset And An Actual Memory Address?

A stack offset is a relative location inside the current function’s stack frame, while an actual memory address is the runtime address produced when the function is called.

For example, the assembly expression:

-20(%rbp)

means:

the memory location whose address is 20 bytes less than the address currently stored in %rbp

If %rbp contains 1000 at runtime, then -20(%rbp) refers to address 980.

The number -20 is an offset or displacement. It is measured in bytes, not in variables, source lines, or stack-frame entries.

So this instruction:

movl    -20(%rbp), %edx

means:

read 4 bytes from the memory location at %rbp - 20 and copy that value into %edx

Q10. What Does It Mean That Stack Memory Uses Higher And Lower Addresses?

Higher and lower addresses do not mean physical up and down. They mean larger and smaller address numbers.

If one memory location has address 1000 and another has address 980, then 1000 is the higher address and 980 is the lower address.

When people say that the stack grows toward lower addresses, they mean that reserving more stack space usually moves the stack pointer toward smaller address numbers.

That is why stack-frame locations are often written as negative offsets from %rbp:

-4(%rbp)
-20(%rbp)
-24(%rbp)

These expressions refer to memory locations below the frame base in address-number terms, not to physical positions.

Q11. Is The Memory Location For A Variable Decided Every Time The Function Is Called?

The relative location is usually chosen by the compiler ahead of time, but the actual address is determined at runtime for each function call.

For example, the compiler may generate code that represents left as:

-20(%rbp)

That relative rule is fixed in the generated assembly.

But when the function is actually called, %rbp receives a runtime address for that specific call. If %rbp is 1000, then -20(%rbp) means address 980. If another call has %rbp as 800, then the same -20(%rbp) expression means address 780.

So there are two different levels of location:

compile time: left is represented as an offset such as -20 from %rbp
runtime: %rbp receives an actual address for this specific function call

Each active function call can have its own stack frame. That is why recursive calls can have separate copies of what looks like the same local variable in the C source.

The key point is that the compiler decides the relative layout of the function’s stack frame, while the actual memory addresses are produced when the program runs.

Q12. Why Does The Instruction Use movl Instead of Just mov?

The suffix l in movl indicates a 32-bit operation in this assembly syntax.

In this example, the C values are int values, and an int is represented here as a 32-bit value. That is why the generated instructions use 32-bit registers such as %eax and %edx.

The rough relationship is:

%rax = 64-bit register
%eax = lower 32 bits of %rax
 
%rdx = 64-bit register
%edx = lower 32 bits of %rdx

So movl is moving a 32-bit value, which matches the int values used by the C function in this lab.

Q13. What Is The Full C-Like Meaning Of These Four Lines?

The assembly code:

movl    -20(%rbp), %edx
movl    -24(%rbp), %eax
addl    %edx, %eax
movl    %eax, -4(%rbp)

can be rewritten conceptually as:

edx = left;
eax = right;
eax = eax + edx;
result = eax;

But this is only a reading aid. The real C program does not have variables named edx or eax. Those are CPU registers.

The source-level meaning is:

int result = left + right;

Q14. What Is The Main Lesson Of This Assembly Example?

The main lesson is that a C expression is represented at the assembly level as concrete movements between memory and registers plus a CPU instruction.

In this specific example:

left   -> loaded from a stack slot into a register
right  -> loaded from a stack slot into a register
add    -> performed by `addl` in registers
result -> stored back into a stack slot

The important lesson is not that every C addition always produces this exact instruction sequence. Different compilers, optimization levels, calling conventions, and target architectures may produce different assembly.

The durable point is that source-level names such as left, right, and result are not preserved as C variables at the assembly level. They are represented through registers, stack locations, and instructions chosen by the compiler.