📘 3.5장 도입: 산술 및 논리 연산
🎯 이 장에서 무엇을 배우는가?
이 장에서는 컴퓨터가 덧셈, 뺄셈, 곱셈 같은 산술 연산이나
AND, OR, NOT 같은 논리 연산을 어떻게 수행하는지를 배운다.
🧠 왜 중요한가?
우리가 프로그램에서 a + b, x * 2, if (x > y) 같은 걸 사용한다. 컴퓨터는 이걸 아주 빠르게 계산하기 위해 레지스터, 비트 연산, 이진수 덧셈기 같은 도구를 사용한다. 이걸 어셈블리어에서 어떻게 처리하는지를 보면 컴퓨터가 똑똑하게 일하는 방식을 이해할 수 있다.
📌 3.5.1 Load Effective Address (LEA, 유효 주소 적재)
🤔 LEA란?
leaq 명령어는 주소를 계산하지만, 메모리에서 값을 읽지는 않는다
💡 예:
leaq 7(%rdx, %rdx, 4), %rax
이건 무슨 뜻인가?
- %rdx에 어떤 값 x가 있다.
- 7(%rdx, %rdx, 4)는
→ 7 + %rdx + 4 * %rdx = 5x + 7이라는 계산을 해준다 - 결과는 %rax에 들어간다.
📌 즉, 단순 계산기로 쓰는 leaq
🧩 leaq 명령어의 형식
leaq [주소형식], 목적지레지스터
- 주소형식은 마치 메모리에서 값을 읽는 형식처럼 생겼지만,
실제로는 계산만 하고 값을 가져오진 않는다 - 목적지 레지스터에는 그 계산 결과(주소 값)가 들어간다.
mov는 메모리에서 값을 가져오지만,
leaq는 그 주소(숫자)만 계산해서 가져온다.
🧮 leaq를 이용한 계산 예시
명령어 | 결과 |
leaq 9(%rdx), %rax | %rax = q + 9 |
leaq (%rdx, %rbx), %rax | %rax = q + p |
leaq (%rdx, %rbx, 3), %rax | %rax = q + 3p |
leaq 2(%rbx, %rbx, 7), %rax | %rax = 2 + 8p |
leaq 0xE(, %rdx, 3), %rax | %rax = 14 + 3q |
leaq 6(%rbx, %rdx, 7), %rdx | %rdx = 6 + p + 7q |
🎯 3.5.2 산술 연산 (Arithmetic Operations)
컴퓨터가 하는 기본 계산
이 절에서는 컴퓨터가 할 수 있는 기본 계산 명령어들을 소개한다.
덧셈, 뺄셈, 곱셈, 반전, 보수 같은 걸 말이다
📦 명령어 종류 요약표
명령어 | 설명 | C 언어와 비교 |
addq S, D | D ← D + S | D += S; |
subq S, D | D ← D - S | D -= S; |
imulq S, D | D ← D * S | D *= S; |
andq S, D | D ← D & S | 비트 AND |
orq S, D | D ← D | S | 비트 OR |
xorq S, D | D ← D ^ S | 비트 XOR |
neg D | D ← -D | 음수로 바꾸기 |
not D | D ← ~D | 비트 반전 |
inc D | D ← D + 1 | 하나 증가 |
dec D | D ← D - 1 | 하나 감소 |
💡 대부분 명령어는 두 오퍼랜드(값)를 사용한다 (binary operation)
예제 C 코드와 어셈블리 비교
ong arith(long x, long y, long z) {
long t1 = x ^ y;
long t2 = z * 48;
long t3 = t1 & 0x0F0F0F0F;
long t4 = t2 - t3;
return t4;
}
→ 이 코드는 다음과 같은 어셈블리로 바뀐다:
xorq %rsi, %rdi ; x ^ y
leaq 0(,%rdx,48), %rax ; z * 48
andl $0x0F0F0F0F, %edi ; & 0x0F0F0F0F
subq %rdi, %rax ; t2 - t3
- leaq를 곱셈처럼 사용한 게 포인트다 (48 = 3 * 16으로 인덱스 연산으로 계산함)
🎯 3.5.3 시프트 연산 (Shift Operations)
🧠 시프트(Shift) 연산이란?
숫자를 비트 단위로 왼쪽이나 오른쪽으로 밀어서 계산하는 방법이다
컴퓨터는 숫자를 0과 1, 즉 비트로 저장한다.
시프트는 이 비트들을 좌우로 움직이면서 새로운 숫자를 만들어내는 것.
명령어 | 설명 | 예 |
sal, shl | 왼쪽 시프트 (x << k) | 2^k * x |
sar | 오른쪽 산술 시프트 (부호 유지) | x / 2^k (음수도 지원) |
shr | 오른쪽 논리 시프트 (0 채움) | 양수에서 / 2^k |
sal과 shl은 같다 sar과 shr은 다르게 동작한다 (부호 처리)
💡 예제: 숫자 8 (이진수로 00001000)
1. 왼쪽 시프트 (shl $1, %rax)
00001000 → 00010000 8 → 16
숫자가 2배가 된다.
2. 오른쪽 논리 시프트 (shr $1, %rax)
00001000 → 00000100 8 → 4
숫자가 반으로 줄어든다.
3. 오른쪽 산술 시프트 (sar $1, %rax)
양수일 땐 shr이랑 똑같이 작동한다.
하지만 음수일 땐 앞에 1이 채워진다!
예: -8 (64비트에서 11111111...11111000)
sar $1, %rax → 여전히 음수 유지된다.
sar은 음수도 처리 가능, shr은 음수에서 틀릴 수 있다.
🧒 쉬운 비유
- shl = 끝에 0을 덧붙여서 자리 올림
(예: 8 → 80처럼 보임) - shr = 앞에 0을 붙여서 숫자 줄이기
- sar = 앞 숫자 그대로 유지하면서 줄이기
(음수도 올바르게 줄인다.)
🧪 정리표 (C 코드 비교)
어셈블리 | C 코드 |
shl $1, %rax | x << 1 |
shr $1, %rax | (unsigned)x >> 1 |
sar $1, %rax | x >> 1 (signed) |
🧠 3.5.4 토의 (Discussion)
🎯 이 절의 핵심
대부분의 어셈블리 연산은 부호 있는 정수(signed)와 부호 없는 정수(unsigned) 모두에 사용할 수 있다.
하지만 오른쪽 시프트는 예외다!
💡 왜 오른쪽 시프트만 다를까?
- 부호 있는 정수(음수 포함): sar → 산술 시프트
- 부호 없는 정수: shr → 논리 시프트
📌 즉, 어떤 시프트를 쓰느냐에 따라 음수의 처리 방식이 다르다
👍 그래서 이게 중요한 이유?
이러한 특성 때문에 컴퓨터는 2의 보수 방식(two’s complement)을 써서
부호 있는 정수도 마치 부호 없는 정수처럼 간단하게 연산할 수 있게 된다.
- 덧셈, 뺄셈, 곱셈은 모두 동일하게 처리 가능
- 단, 나눗셈이나 시프트만 구별 필요
이게 바로 2의 보수가 컴퓨터에서 부호 있는 숫자를 표현하는 표준 방식이 된 이유이다.
🧠 3.5.5 특수 산술 연산 (Special Arithmetic Operations)
🎯 이 절의 핵심
때때로 계산 결과가 너무 커서 64비트로는 부족하다.
그래서 128비트(16바이트) 연산도 필요하다
📦 128비트 연산은 언제 필요할까?
- 64비트 숫자 × 64비트 숫자 = 최대 128비트 결과 필요
- 이럴 땐 %rax + %rdx 두 개의 레지스터를 붙여서 128비트처럼 사용한다.
💡 명령어 요약
명령어 | 설명 | 결과 저장 장소 |
imulq S | 부호 있는 곱셈 | %rdx:%rax ← S × %rax |
mulq S | 부호 없는 곱셈 | %rdx:%rax ← S × %rax |
cqto | %rax의 부호 확장 → %rdx에 넣기 | 128비트 만들기 준비 |
idivq S | 부호 있는 나눗셈 | %rax ← 몫, %rdx ← 나머지 |
divq S | 부호 없는 나눗셈 | 위와 같음 |
%rdx:%rax는 두 레지스터를 합쳐서 128비트처럼 사용하는 걸 의미한다.
📊 예시 비유
- %rax: 계산기 아래쪽 반
- %rdx: 계산기 위쪽 반
- 둘이 합쳐서 큰 계산기가 되는 것이다.
예를 들어:
movq $10000000000, %rax movq $0, %rdx idivq $10
→ %rax에는 몫, %rdx에는 나머지가 저장된다.
✅ 마무리 요약
- 3.5.4: 대부분 연산은 부호 유무에 관계없이 쓸 수 있지만, 시프트는 예외
- 3.5.5: 128비트 결과가 필요한 곱셈·나눗셈 연산은 %rax, %rdx를 함께 사용
- imulq, mulq, idivq, divq, cqto 등은 특수한 산술 상황에 사용된다.
'크래프톤 정글 (컴퓨터 시스템: CSAPP) > 3장 프로그램의 기계수준 표현' 카테고리의 다른 글
컴퓨터 시스템 : CSAPP 3장 정리 - 3.6 장 제어문 Part.2 (0) | 2025.04.05 |
---|---|
컴퓨터 시스템 : CSAPP 3장 정리 - 3.6 장 제어문 Part.1 (0) | 2025.04.05 |
컴퓨터 시스템 : CSAPP 3장 정리 - 3.4 장 정보 접근하기 Part.3 (0) | 2025.04.05 |
컴퓨터 시스템 : CSAPP 3장 정리 - 3.4 장 정보 접근하기 Part.2 (0) | 2025.04.05 |
컴퓨터 시스템 : CSAPP 3장 정리 - 3.4 장 정보 접근하기 Part.1 (0) | 2025.04.05 |