Course / 13 Reversing / Lesson 01 of 05

Enough C and assembly to follow a compare and a jump

Estimated time: 18 min reading · 16 min activity

A small program can make a decision in source code and express the same decision through processor instructions after compilation. Source is the text a programmer writes. A compiler translates it toward machine code; assembly is a readable notation for machine instructions. The exact instructions depend on the compiler, its options and the target machine.

A function is a named operation with inputs and a return value. int means an integer, a whole-number value. The function mark receives x and compares it with 7. The operator == tests equality; return ends the function and supplies a result. Braces group statements, parentheses surround inputs or conditions, and semicolons end statements.

Read Compiled and interpreted first if you want the fuller build explanation; it appears next in the catalog. You can still follow this page from the primer below. The supplied comparison is a function without main, the usual entry function in a complete hosted C program. It is not a standalone executable.

Before you begin

Estimated time
18 min reading, 16 min activity. Setup and optional practice may take longer.
Where you work
Read the supplied C/Python source and clearly labeled conceptual models in any current desktop or mobile browser. No compiler, binary execution, debugger, tracer or Ghidra installation is required. Function-only C sources are not standalone programs.
Without a lab
Trace the source or model on paper and record the condition, chosen branch and evidence limit. No matched lesson ELF, disassembly, debugger session or Ghidra export is supplied. Historical observations retain their separate context. Reading works without JavaScript. Checking requires JavaScript and a secure context; saving also requires usable storage.

After this lesson you can:

  • Trace mark(7) through the source to the equal-path return.
  • Use the conceptual model to name the equal path and the other path.
  • Trace lane at 5 and at 1 without treating the model as a disassembly.

01Example

Source trace of mark, for the integer 7. This is a reading of compare.c. It is not a program run, and the model under it is not a disassembly.

Source: if (x == 7) return 1; otherwise return 0.
Input on this card: 7
7 equals 7, so the source takes the equal path.
Source trace result: 1

Conceptual instruction model. Not compiler output.
Compare the integer with 7.
Equal: path that returns 1.
Not equal: the other path.
No address, opcode, or register was captured.

02Where a compare lives

In compare.c, if (x == 7) selects the block returning 1 when the equality is true. Otherwise execution reaches return 0. These integers are the function's chosen results; a return value of 0 is not universally a failure. Trace the source rule before trying to name a processor instruction.

A conditional jump is an instruction that may move execution to another location depending on a condition. A register is a small processor storage location, and an address identifies a location in memory. The conceptual branch card names no real registers, opcodes or addresses. An opcode encodes an instruction; none was captured here.

A recorded link attempt failed because this function-only source has no main. That record is separate from the unrun -O0 -g candidate instruction. There is no matched executable or disassembly for this lesson. A source prediction does not establish what a particular compiled binary contains.

Trace a small C compare, and keep a conceptual jump model separate from compiler output.Model. A teaching model drawn by hand. It shows the idea, not real tool output.

Read the full explanation below.

Source prediction; no binary was run. No compiler-generated instruction listing is supplied.

/* Original teaching source. Not compiled. */
int mark(int x) {
    if (x == 7) {
        return 1;
    }
    return 0;
}
Supplied input
7
Comparison target
7
Equal?
not compared
Function return
not returned
Equal → source return 1Other → source return 0

A source branch explains the prediction. It does not establish emitted opcodes, captured registers, an observed function run or a process exit.

Source input x = 7; no binary or register was observed.

Follow the explanation

  1. Source input x = 7; no binary or register was observed.
  2. The supplied source compares x == 7; with x = 7 this is true.
  3. Select the equal source path; the instruction view remains conceptual.
  4. The source trace reaches return 1; no function was run.

Complete supplied scalar source traces

mark(7), source trace
/* Original teaching source. Not compiled. */
int mark(int x) {
    if (x == 7) {
        return 1;
    }
    return 0;
}

Supplied input 7 compared with 7: equal; source prediction returns 1.

Source prediction; no binary was run. The instruction-level relationship remains conceptual; no disassembly, register capture or process exit observation is supplied.

A source branch can be traced without claiming captured machine instructions or an observed function run.

03Compilation primer

A C build can preprocess source, compile it, assemble the resulting instructions and link object files into an executable. Linking combines compiled pieces with required support code. Function-only sources can be compiled as components, but cannot become the intended standalone hosted program without an entry function and appropriate linking.

The printed command gcc -O0 -g -o mark compare.c is an unrun historical candidate, not a complete working build recipe for this function-only file. -O0 disables most optimization passes, -g requests debugger information and -o names the output. These flags neither add main nor guarantee an instruction sequence. Do not run the candidate to finish this text activity.

/* Original teaching source. Not compiled. */
int mark(int x) {
    if (x == 7) {
        return 1;
    }
    return 0;
}

Download the mark source

Historical/candidate build record for compare.c. This file contains a function without main.

Historical QA, 2026-10-12: gcc13.3.0 with gcc -Wall -Wextra -o prog compare.c failed to link because main was undefined. No executable, object file or assembly listing was retained.

Unrun historical candidate, not a working standalone build recipe:
gcc -O0 -g -o mark compare.c

-O0 disables most optimization passes; it does not guarantee one instruction listing.
-g requests debugger information; -o mark names the output.
These options do not supply main. Do not run this command for the lesson.
A later component build or harness would need its own explicit design and evidence record.

Download the unrun build instruction

Conceptual instruction model. Not compiler output. Not a disassembly.

Decision: compare the function's integer with the number in the condition.
If the comparison says equal, take the path that returns the equal-path value.
If the comparison says not equal, take the other path.

No address, opcode, or register was captured.
A later owned build can replace this card with a disassembly from that build.
Until then, this card is only a picture of the decision.

Download the conceptual branch model

04Trace lane

Use the separate lane function to practice the same source-tracing method with different values. A function call such as lane(5) supplies 5 as n. Record the condition, whether it is true and which return is reached. The conceptual model remains separate from a real disassembly.

/* Activity source. Different numbers from the question. Not compiled. */
int lane(int n) {
    if (n == 5) {
        return 2;
    }
    return 6;
}

Download the lane source

  1. Read lane. Write the condition and both return values in your notes.
  2. Trace n equal to 5. Check: the condition is true, so the source trace returns 2.
  3. Trace n equal to 1. Check: the condition is false, so the source trace returns 6.
  4. Stop. Do not run gcc. A captured disassembly is still missing, and the model does not fill that gap.

05Optional challenge

Point at the not-equal path in the conceptual model and write the lane source line it corresponds to when n is 1. About ten minutes. There is still no recorded branch instruction to match.

06Fresh cases for the checks

Use these fictional cases for the checks below. They have different inputs from the worked examples. Read them here or make notes; no installation or external service is needed.

Branch case A: fresh uncompiled sourceOwned fixture. An original file made for this course. Follow the activity's instructions in your own lab.

int twig(int n) {
  if (n == 9) { return 4; }
  return 8;
}
Conceptual model: compare n with 9; equal takes path E; not-equal takes path N.
Paths model the source. No instructions or run were captured.

07Explain your evidence

Optional written self-check: explain one decision using the supplied case. No tool run is required.

Check your explanation: substitute the input; state the equality result, selected branch and reached return; distinguish a source prediction from compiled instructions and an observed run.

08Common mistakes

If the trace for 7 comes out as 0, the condition was read backwards. 7 matches 7, so mark takes the equal path on the worked card.

If a register name or an address is added to the model, that detail was invented. The card leaves those blank on purpose.

If gcc is started to see the real listing, stop. This page's check uses the source trace. You do not need a later build for this page.

References