2025. 10. 20. 15:19ㆍCSAPP
ㅈㄱㄴ이다.
미안하지만 .1장을 요약할 때 마다 하루나 걸려서 너무 힘든 관계로 남은 3장은 GPT를 통해 요약했다.
이 못나고 게으르고 시간이 없는 필자를 용서해주면 좋겠다... 미안하다.....
요약은 Gpt 5 pro 모델에 프롬프트와 cs:app 3장 영문을 준 뒤에 했다.
3.5 산술과 논리 연산
이 장에서는 플래그(조건 코드)를 처음 만난다.
CPU는 연산을 할 때 결과를 저장할 뿐 아니라 “결과가 어떤 상태인지”도 플래그에 기록한다.
| ZF | 결과가 0인가? |
| SF | 음수인가? |
| CF | 자리올림(캐리) 발생? |
| OF | 오버플로 발생? |
예를 들어, cmpq %rax, %rbx는 실제로는 %rbx - %rax를 계산하지만 결과는 버리고,
그 대신 조건 코드만 설정한다.
이 플래그는 곧 분기(jmp, je, jne, jl...) 명령의 근거가 된다.
특이한 명령 하나:
leaq는 주소 계산용 명령이지만, 사실상 덧셈/곱셈에도 쓴다.
게다가 플래그를 건드리지 않는다.
즉, "주소 계산기"이자 “조건 안전 계산기”.
3.6 제어 흐름 (if, while, for, switch)
모든 제어문은 결국 “조건 점프”로 구현된다.
- if문 → 조건 코드 확인 → 분기(je, jne, jl, ...)
- while문 → 조건 검사 → 루프 본문 → 다시 점프
- for문 → while의 변형 (초기화 + 조건 + 증감)
- switch문 → 점프 테이블(jump table) 사용 (케이스가 많을 때 빠름)
💡 cmov (조건부 이동) 명령은 분기 없이 결과만 바꾼다.
예측 실패로 인한 성능 하락을 줄이는 멋진 최적화 도구다.
3.7 프로시저 (함수 호출)
함수를 호출하면 호출 규약(calling convention)에 따라 인자와 반환값이 전달된다.
| 인자(1~6) | %rdi, %rsi, %rdx, %rcx, %r8, %r9 |
| 반환값 | %rax |
| 호출자 보존 | %r10, %r11 |
| 피호출자 보존 | %rbx, %rbp, %r12~%r15 |
call 명령은
- 복귀 주소를 스택에 push하고
- 함수 시작 지점으로 점프한다.
ret 명령은
- 스택에서 주소를 pop하고
- 그곳으로 돌아간다.
스택은 작은 주소 쪽으로 성장한다.
즉, push 하면 %rsp -= 8, pop 하면 %rsp += 8.
3.8 배열
배열은 “메모리 속에 연속된 공간”이다.
원소 a[i]의 주소는 간단하다:
예:
- (%rdi, %rsi, 4) → a[i] (int 배열의 i번째 값)
- ((i × 열 수) + j) 계산으로 다차원 배열도 접근한다.
3.9 구조체와 공용체
C의 구조체는 멤버 순서대로 메모리에 저장되지만,
CPU가 빠르게 접근하도록 정렬(alignment) 규칙을 지킨다.
그래서 멤버 사이에 패딩(padding)이 끼어 공간이 비는 일이 있다.
예:
총 8바이트(중간에 3바이트 패딩).
멤버 순서만 바꿔도 크기가 달라진다!
3.10 제어와 데이터 결합 + 보안
C의 강력함 = 자유.
자유 = 책임.
책임 안 지면 → 버퍼 오버플로우 💣
스택에 할당된 배열을 넘치게 채우면,
리턴 주소까지 덮어쓸 수 있다.
공격자는 이를 이용해 임의 코드로 점프한다.
💥 그래서 OS는 방어막을 쳤다:
- ASLR (주소 무작위화): 실행마다 메모리 주소를 섞는다.
- Stack Canary: 복귀 주소 앞에 “수호자 값”을 둬서 손상 시 탐지.
- NX bit: 스택 영역을 실행 불가로 만든다.
이 세 가지가 합쳐져 현대 시스템은 훨씬 안전해졌다.
3.11 부동소수점
정수 연산과 다르게, 실수(float/double)는 XMM 레지스터를 사용한다.
즉, movsd, addsd, mulsd, divsd 같은 명령으로 계산한다.
여러 개의 실수를 한 번에 처리하는 벡터 명령(AVX)도 존재한다.
실수 인자는 XMM 레지스터로 전달되고, 반환값도 XMM0에 담긴다.
3.12 요약 정리
3장은 CS:APP 전체의 “기계 언어 입문서”다.
이 장만 이해하면
- C 코드가 어셈블리로 어떻게 바뀌는지,
- 스택과 레지스터가 어떻게 협업하는지,
- 왜 보안과 최적화가 레벨 낮은 곳에서 시작되는지
전부 한눈에 보인다.
⚙️ 추가 — 실제 세계 업데이트 (Beyond CS:APP 3e)
- 현대 리눅스는 PIE(위치 독립 실행 파일) 과 ASLR을 기본 활성화함.
- 기본 컴파일 옵션에는 스택 보호(-fstack-protector-strong), CET(Control-flow Enforcement)가 들어감.
- Windows x64는 다른 호출 규약(rcx, rdx, r8, r9)을 사용하고, Red Zone이 없다.
- 대부분의 CPU는 AVX2 이상을 기본 지원하며, x87 FPU는 역사 속으로 사라짐.
💬 마무리
이제 “if, for, struct, 함수 호출” 같은 게 전부
“cmp, jmp, leaq, call, ret”으로 바뀌는 과정이 보일 것이다.
C는 하드웨어의 시뮬레이터다.
이걸 읽을 수 있으면, 컴퓨터의 사고방식이 눈앞에 펼쳐진다.
똥글 미안하다.
생성형 AI로 글을 쓰는 내가 나도 싫다 미안하다 ㅜㅜ
'CSAPP' 카테고리의 다른 글
| [Week6 - CSAPP] 9.1 - 톰 킬번 없었으면 님들 사펑이랑 GTA5 못함 ㄹㅇ (0) | 2025.10.22 |
|---|---|
| [Week6 - CSAPP] 3.4 - 여친 만드는 법 : 어셈블리어 배우기 (3) | 2025.10.18 |
| [Week5 - CSAPP] 3.3 - 데이터의 형식 (0) | 2025.10.17 |
| [Week3 - CSAPP] 3.2 - 프로그램의 인코딩 (0) | 2025.10.01 |
| [Week3 - CSAPP] 3.1 - 역사적 관점(근데 약간 이상한) (0) | 2025.09.19 |