Notice
Recent Posts
Recent Comments
Link
«   2026/11   »
일 월 화 수 목 금 토
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

헤맨 만큼 내 땅이다

퀴즈 5번 : 어셈블리 → C 코드 복원 본문

week5

퀴즈 5번 : 어셈블리 → C 코드 복원

신속다람 2026. 9. 22. 15:37

cmpl / jle 조건부 분기를 읽다가 막혔던 지점들 정리


문제 상황

cmpl $0, %edi
jle  .L1
movl $1, %edx
jmp  .L2
.L1:
movl $0, %edx
.L2:
movl %edx, %eax
ret
int function(int x) {
    int y;
    if ( ____(1) )
        _____(2);
    else
        y = 0;
    return ____(3);
}

트러블 1 — %edi가 갑자기 왜 나오지? x는 어디 있는 거야?

증상: 코드 어디에도 x라는 글자가 없는데 갑자기 %edi가 등장해서 당황함.

원인: 함수 인자는 코드에 명시적으로 "담기는" 과정이 안 보여요. 함수가 시작되는 순간, 이미 첫 번째 인자가 %edi(4바이트 정수 인자 규칙)에 담긴 채로 시작하기 때문이에요.

해결: 어셈블리에서 %edi를 보면 자동으로 **"이건 x다"**라고 치환해서 읽는 습관을 들이기. 별도의 "대입" 코드가 있어야 하는 게 아니라, 함수 진입 시점부터 이미 그렇게 세팅되어 있다는 걸 전제로 깔고 읽어야 함.


트러블 2 — cmp가 뭔지 몰라서 첫 줄부터 막힘

증상: cmpl $0, %edi를 보고 "이게 뭘 하는 명령어인지" 전혀 감이 안 옴.

원인: cmp를 배운 적이 없거나, 배웠어도 "빼기랑 뭐가 다른지"가 명확하지 않았음.

해결 — 핵심 비유: 저울에 물건 두 개를 올려서 "몇 그램 차이 나는지"는 필요 없고 "어느 쪽이 무거운지"만 알고 싶은 상황과 같음.

cmpl $0, %edi
   ↓
x - 0을 계산은 하되, 그 결과값은 버림
대신 "결과가 양수/음수/0이었는지"만 CPU의 플래그(표시등)에 기록

왜 sub(진짜 빼기)를 안 쓰는지: sub를 쓰면 계산 결과가 레지스터에 그대로 덮어써져서, x의 원래 값을 잃어버림. cmp는 "비교만 하고 원본은 보존"하기 위한 전용 명령어.


트러블 3 — jle가 정확히 뭘 비교하는 건지 모르겠음

증상: jle .L1이 "무엇을" "무엇과" 비교해서 점프하는 건지 연결이 안 됨.

원인: jle는 그 자체로는 아무것도 비교하지 않음 — 바로 앞줄 cmp가 세팅해놓은 플래그를 읽기만 하는 명령어라는 연결고리를 놓침.

해결:

jle = jump if less or equal (작거나 같으면 점프)

바로 앞 cmp에서 계산한 게 "x - 0" 이었으므로:
jle의 조건 = "x - 0 ≤ 0" = "x ≤ 0"

정리: cmp가 "재료(플래그)"를 만들고, 바로 다음에 오는 조건부 점프가 그 재료를 "소비"한다는 2단계 구조로 항상 짝지어 읽기.


트러블 4 (가장 헷갈렸던 지점) — 왜 x ≤ 0이 아니라 x > 0으로 뒤집혀서 나오는가

증상: 분명 jle의 점프 조건은 x ≤ 0인데, 정답 C 코드에는 **if (x > 0)**이라고 반대로 적혀있음. "그냥 조건 그대로 쓰면 안 되나?"

원인 — 질문 자체가 다르다는 걸 놓침:

  • 점프 조건이 답하는 질문 = "언제 else로 도망갈까?"
  • if 조건이 답하는 질문 = "언제 then을 실행할까?"

이 둘은 같은 게 아니라 서로 반대되는 상황을 가리킴.

코드 구조로 확인:

cmpl $0, %edi
jle  .L1              ← "조건 맞으면(x≤0) else로 도망가라"
movl $1, %edx           ← 도망 안 갔을 때만 실행 = then 절 (y=1)
jmp  .L2
.L1:
movl $0, %edx              ← 도망가서 도착 = else 절 (y=0)

해결 — 뒤집기 공식:

점프 조건(jle):  x ≤ 0     →  이건 "else로 가는 조건"
        ↓ 반대로 뒤집기
then 조건:      x > 0     →  이게 실제 if문에 들어가는 조건

비유: "비가 오면 우산을 챙겨라"는 규칙만 있을 때, "우산을 안 챙기는 상황"이 궁금하면 그 규칙을 뒤집어야(=비가 안 오면) 답이 나오는 것과 같은 원리.


최종 정답

int function(int x) {
    int y;
    if (x > 0)          // (1)
        y = 1;            // (2)
    else
        y = 0;
    return y;                // (3)
}

재발 방지 체크리스트 — 다음에 비슷한 문제 만나면

  1. 인자 → 레지스터 매핑부터 확인: %edi, %esi 등이 어떤 C 변수에 대응하는지 먼저 표시해두기
  2. cmp 줄 발견 시: "오퍼랜드2 - 오퍼랜드1"이 뭔지부터 적어보기 (여기선 x - 0)
  3. 조건부 점프(jle, je, jg...) 발견 시: 그 점프가 "어디로, 무슨 조건으로" 가는지 적기
  4. ★ 가장 중요: 조건부 점프는 대부분 **"else로 가는 티켓"**이지 "then으로 가는 티켓"이 아니므로, if문 조건을 쓸 땐 점프 조건을 반드시 반대로 뒤집는다

'week5' 카테고리의 다른 글

트러블슈팅2  (0) 2026.09.30
02 Stack Buffer Overflow (off-by-one)  (0) 2026.09.22