[Theory] C Language vs Assembly Language: A Complete Mapping Guide! ๐Ÿงฉ (Building Foundational Strength for Reversing)

Hello, aspiring security professionals! ๐ŸŒฑ

When studying malware analysis or reverse engineering, you inevitably encounter a huge barrier: Assembly Language.

Seeing a black screen filled with unknown English acronyms like MOV, LEA, CMP, JE… naturally makes you wonder, “Who am I? Where am I?” ๐Ÿ˜ตโ€๐Ÿ’ซ

But don’t be intimidated! Assembly language is not alien. It’s simply C language (a high-level language) in different attire. Compilers translate C language into machine code according to predefined rules (Patterns), so if you know these ‘conversion rules (Mapping)’, you can read assembly language fluently.

Today, we will thoroughly explore the core of reverse engineering: the 1:1 mapping structure between C language and assembly language. Understanding this principle will allow you to see the flow of code even without a decompiler! ๐Ÿš€


1. Variable Assignment ๐Ÿ“ฅ

Assigning a value to a variable in C language is expressed as data movement (Move) in assembly.

๐Ÿ“Œ C Language

int a = 10;
int b = a;

โš™๏ธ Assembly

MOV [RBP-4], 0xA    ; 1. ๋ฉ”๋ชจ๋ฆฌ(๋ณ€์ˆ˜ a์˜ ์œ„์น˜)์— 10(0xA)์„ ๋„ฃ๋Š”๋‹ค.
MOV EAX, [RBP-4]    ; 2. ๋ณ€์ˆ˜ a์˜ ๊ฐ’์„ ๋ ˆ์ง€์Šคํ„ฐ(EAX)๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.
MOV [RBP-8], EAX    ; 3. ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ(๋ณ€์ˆ˜ b์˜ ์œ„์น˜)์— ๋„ฃ๋Š”๋‹ค.
  • Explanation:
  • The CPU cannot directly move data from memory to memory. Therefore, it moves data via a register (temporary storage) like EAX.
  • Forms like [RBP-4] refer to a stack memory address (local variable).
  • Key point: You can think of MOV A, B as A = B.

2. Arithmetic Operations ๐Ÿงฎ

Operations like addition and subtraction are very intuitive.

๐Ÿ“Œ C Language

a = a + 5;
a++;

โš™๏ธ Assembly

ADD [RBP-4], 5      ; a = a + 5 (ADD: ๋”ํ•˜๊ธฐ)
INC [RBP-4]         ; a++ (INC: 1 ์ฆ๊ฐ€)
  • Explanation:
  • ADD: Addition
  • SUB: Subtraction
  • INC: Increment by 1
  • DEC: Decrement by 1
  • IMUL / IDIV: Multiplication / Division

3. Conditional Statements (If-Else) โš–๏ธ

These are branching statements that change the flow of a program. In assembly, they consist of two steps: comparison (CMP) and jump (JUMP).

๐Ÿ“Œ C Language

if (a == 10) {
    // True Block
    b = 1;
} else {
    // False Block
    b = 0;
}

โš™๏ธ Assembly

CMP [RBP-4], 0xA    ; 1. a์™€ 10์„ ๋น„๊ตํ•œ๋‹ค. (์‹ค์ œ๋กœ๋Š” a - 10์„ ํ•ด๋ด„)
JNE 0x401050        ; 2. ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์ง€ ์•Š๋‹ค๋ฉด(Not Equal), Else ๋ธ”๋ก(0x401050)์œผ๋กœ ์ ํ”„!

; --- True Block ---
MOV [RBP-8], 1      ; b = 1
JMP 0x401060        ; Else ๋ธ”๋ก์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ํƒˆ์ถœ!

; --- False Block (0x401050) ---
MOV [RBP-8], 0      ; b = 0
  • Explanation:
  • CMP A, B: Compares A and B. (Internally performs A – B and considers them equal if the result is 0)
  • JE (Jump Equal): Jumps if equal
  • JNE (Jump Not Equal): Jumps if not equal
  • JG / JL: Jumps if greater / Jumps if less
  • Remember that the { } block structure of high-level languages changes into a GOTO (jump) form in assembly!

4. Loops (For / While) ๐Ÿ”„

Loops are a combination of conditional statements and jumps. They have a cyclic structure where the code goes down and then jumps back up.

๐Ÿ“Œ C Language

for (int i = 0; i < 10; i++) {
    sum += i;
}

โš™๏ธ Assembly

MOV [RBP-4], 0      ; i = 0 (์ดˆ๊ธฐํ™”)
JMP Check_Condition ; ์กฐ๊ฑด ํ™•์ธํ•˜๋Ÿฌ ๊ฐ€๊ธฐ

Loop_Start:         ; ๋ฃจํ”„ ์‹œ์ž‘ ์ง€์ 
MOV EAX, [RBP-4]    ; i ๊ฐ’์„ ๊ฐ€์ ธ์˜ด
ADD [RBP-8], EAX    ; sum += i
INC [RBP-4]         ; i++ (์ฆ๊ฐ)

Check_Condition:    ; ์กฐ๊ฑด ํ™•์ธ ์ง€์ 
CMP [RBP-4], 0xA    ; i์™€ 10 ๋น„๊ต
JL Loop_Start       ; i < 10 (์ž‘์œผ๋ฉด) Loop_Start๋กœ ๋‹ค์‹œ ์ ํ”„!
  • Explanation:
  • A C language for loop is broken down into the sequence: initialization -> condition check -> body -> increment/decrement -> condition check.
  • If you see JMP or Jcc instructions with an upward arrow in assembly code, you can think, “Ah, this is a loop!”

5. Function Call ๐Ÿ“ž

This is the most important Calling Convention in reversing. Before calling a function, you prepare parameters (arguments), and after the function finishes, you receive the return value.

๐Ÿ“Œ C Language

int result = Add(10, 20);

โš™๏ธ Assembly (x64 Standard)

MOV EDX, 20         ; 2๋ฒˆ์งธ ์ธ์ž(20)๋ฅผ EDX(๋˜๋Š” RSI) ๋ ˆ์ง€์Šคํ„ฐ์— ๋„ฃ์Œ
MOV ECX, 10         ; 1๋ฒˆ์งธ ์ธ์ž(10)๋ฅผ ECX(๋˜๋Š” RDI) ๋ ˆ์ง€์Šคํ„ฐ์— ๋„ฃ์Œ
CALL 0x401200       ; Add ํ•จ์ˆ˜ ํ˜ธ์ถœ (์Šคํƒ์— ๋ณต๊ท€ ์ฃผ์†Œ ์ €์žฅํ•˜๊ณ  ์ด๋™)
MOV [RBP-4], EAX    ; ๊ฒฐ๊ณผ๊ฐ’(EAX)์„ result ๋ณ€์ˆ˜์— ์ €์žฅ
  • Explanation:
  • Parameter Passing: In an x64 environment, arguments are primarily passed in registers (RDI, RSI, RDX, RCX…). (x86 uses stack PUSH)
  • CALL: Jumps to the address where the function is located. At this time, the return address after the function finishes is secretly saved on the stack.
  • Return Value (RAX/EAX): The result of a function’s execution is always stored in the EAX (or RAX) register. Therefore, checking EAX immediately after a CALL will reveal the return value.

๐Ÿ’ก Tip: Study with AI

It’s okay if the patterns you learned today aren’t familiar yet. We have AI!

If you encounter unfamiliar assembly code during practice, ask it this:

“Decompile this assembly code into C language and explain its structure (if, for, etc.)!”

AI will interpret the code based on the mapping rules we just learned. But remember, knowing the theory and seeing the results is vastly different from seeing them without understanding the theory! ๐Ÿ˜‰

Conclusion ๐ŸŽ

C language and assembly language are like ‘two sides of the same coin’.

If you gain the ability to imagine the other side (C language) just by looking at one side (assembly), you’ve already grasped the ticket to becoming an intermediate analyst.

Next time, based on this theory, we will conduct a magical practical session where we ask AI to “reimplement this assembly code in Python.”

Have a great time reversing today! Fighting! ๐Ÿ’ช



Comments

Leave a Reply

Your email address will not be published. Required fields are marked *