CSAPP/3장

[CSAPP] 3-5 산술연산과 논리연산

넌뭐가그렇게중요해 2025. 4. 8. 19:18

1. 산술 및 논리 연산의 개요

컴퓨터는 기본적으로 데이터를 처리하기 위해 다양한 연산을 수행합니다. 이러한 연산은 크게 산술 연산과 논리 연산으로 구분할 수 있습니다. 

  • 산술 연산 : 덧셈, 뺄셈, 곱셈, 나눗셈과 같은 수학적 계산을 수행합니다. 
  • 논리 연산 : AND, OR, NOT과 같이 비트 단위의 논리적 판단을 수행합니다.

이러한 연산들은 컴퓨터 내부에서 어셈블리어 명령어로 표현되며, 각 명령어는 특정한 기능을 수행합니다. 


2. 유효 주소 적재(Load Effective Address)

LEA(Load Effective Address) 명령어는 메모리 주소를 계산하여 그 결과를 레지스터에 저장합니다.
즉, 실제 메모리에서 데이터를 읽어오는 것이 아니라, "주소 계산" 결과를 얻어내는 역할을 합니다.

e.g. in C

int array[5] = {10, 20, 30, 40, 50};
int *ptr = &array[2];

위 코드에서 ptr은 array 배열의 세 번째 요소의 주소를 가리킵니다. 이를 어셈블리어로 표현하면 leaq 명령어를 사용하여 해당 주소를 계산하고 레지스터에 저장할 수 있습니다. 

in Assembly

leaq 8(%rbp), %rax

위 명령어는 rbp 레지스터의 값에 8을 더한 주소를 계산하여 rax 레지스터에 저장합니다. 이는 배열의 특정 요소에 접근하기 위한 주소 계산에 해당합니다. 


3. 단항 및 이항 연산

연산자는 피연산자의 수에 따라 단항 연산자이항 연산자로 나뉩니다.

단항 연산(Unary Operations)

  • 정의 : 한 개의 피 연산자에 대해 수행되는 연산
  • 예시 :
    • incq %rax : %rax의 값을 1 증가시킵니다. 

e.g. in C

int a = 5;
a = -a;  // 부호 변경

e.g. in Assembly

movl $5, %eax   ; %eax에 5 저장
negl %eax       ; %eax의 값을 부호 반전 (5 → -5)

이항 연산(Binary Operations)

  • 정의: 두 개의 피연산자에 대해 수행되는 연산
  • 예시 :
    • addq % rbx, %rax : %rbx 의 값을 %rax에 더합니다. 

e.g. in C

int a = 5, b = 3;
int c = a + b;

in Assembly

movl $5, %eax   ; %eax에 5 저장
movl $3, %ebx   ; %ebx에 3 저장
addl %ebx, %eax ; %eax = %eax + %ebx (결과: 8)

 


4. 쉬프트 연산(Shift Operations)

쉬프트 연산은 데이터를 비트 단위로 좌측이나 우측으로 이동시키는 연산입니다. 이 연산은 빠른 곱셈이나 나눗셈 효과를 얻기 위해 사용됩니다. 

쉬프트 연산의 종류

연산 종류 설명 e.g.(C, Assembly)
논리적 좌측
쉬프트
비트를 좌측으로 이동시키며, 오른쪽에는 0을 채움 C : b = a << 1;
Assemvly : shll $1, %eax(val : 4 → 8)
논리적 우측
쉬프트
비트를 우측으로 이동시키며, 왼쪽에는 0을 채움 C : b = a >> 1; (음수가 아닌 경우)
Assemvly : shrl $1, %eax
산술적 우측
쉬프트
비트를 우측으로 이동시키며, 왼쪽에는 최상위 비트(부호 비트)를 복사 C : b = a >> 1; (음수 처리 시, 구현에 따라 산술적 우측 쉬프트)
Assembly : sarl $1, %eax

 

논리적 좌측 쉬프트

e.g. in C

int a = 4;      // 0000 0100
int b = a << 1; // 0000 1000, 왼쪽으로 1비트 이동 (2배 곱셈 효과)

in Assembly

movl $4, %eax   // eax 레지스터에 4 저장
shll $1, %eax   // eax 값을 왼쪽으로 1비트 이동 → 결과: 8

산술적 우측 쉬프트 

e.g. in C

int a = -8;        // 이진수 표현은 부호 비트를 포함한 형태
int b = a >> 1;    // -8 >> 1은 산술적 우측 쉬프트로, 부호를 유지하며 4로 나누는 효과

in Assembly

movl $-8, %eax  ; %eax에 -8 저장
sarl $1, %eax   ; %eax 값을 산술적 우측으로 1비트 이동 → 결과: -4

 

마치며

 

  • 효율성:
    • LEA 명령어는 단순히 데이터를 이동시키는 것이 아니라, 복잡한 주소 계산을 한 번에 수행해 CPU의 연산 효율을 높입니다.
  • 정확성:
    • 쉬프트 연산은 곱셈이나 나눗셈을 빠르게 처리할 수 있지만, 비트 단위로 처리하기 때문에 데이터의 부호나 오버플로우 문제를 신경 써야 합니다.
  • 응용:
    • 단항 및 이항 연산은 기본적인 산술 연산 외에도, 조건문이나 반복문에서 중요한 역할을 하며, 시스템 프로그래밍과 저수준 최적화에 필수적입니다.