[CSAPP 3장 완전 정복] 3.5 기계 수준의 연산, 어떻게 작동할까?

2025. 4. 5. 19:40·크래프톤 정글/컴퓨터구조(CSAPP)

기계 수준의 연산, 어떻게 작동할까?

C 코드에서 우리가 아무렇지 않게 사용하는 +, -, *, &, | 등의 연산자들은 기계 수준에서 명령어 형태로 정확히 변환됩니다. 이번 절에서는 산술 및 논리 연산을 수행하는 명령어들이 어셈블리어에서 어떤 방식으로 표현되는지 간략히 알아보겠습니다.

 

 

산술 연산 명령어

명령어 설명
add 두 값을 더함
sub 두 값을 뺌
imul 정수 곱셈
inc / dec 1 증가 / 감소
neg 부호 반전 (0 - x)
예시) addq %rax, %rdx  →  %rdx = %rdx + %rax

 

 

즉시값을 사용하는 연산

일반적인 연산 외에도, 즉시값(Immediate Value)을 이용한 연산도 가능합니다.

addq $10, %rax    ; %rax에 10 더하기

즉시값은 $ 기호로 표현되며, 레지스터나 메모리에 바로 값을 더할 수 있습니다.

 

 

효과적인 주소 계산: leaq 명령어

leaq(Load Effective Address) 명령어는 이름과 달리 메모리 접근 없이 주소 계산만 수행합니다. 일반적인 산술 명령어와 비슷하게 보이지만, 메모리에서 값을 불러오는 것이 아니라 계산된 값을 단순히 레지스터에 저장하는 점이 특징입니다.

leaq 7(%rdx,%rdx,4), %rax   ; %rax = %rdx + 4 * %rdx + 7 = 5 * %rdx + 7

이처럼 복합적인 덧셈 및 곱셈을 한 줄에 처리할 수 있어, 배열 인덱싱이나 포인터 연산에 자주 활용됩니다. 메모리 접근이 없다는 점에서 계산 비용도 적습니다.

 

 

논리 연산 명령어

명령어 설명
and 비트 AND
or 비트 OR
xor 비트 XOR
not 비트 반전

이 명령어들은 비트 단위로 작동하며, 종종 비트 마스킹(Bit Masking)이나 조건 분기 최적화에 사용됩니다.

예: xor %rax, %rax  →  효율적인 0 초기화 (0을 직접 할당하는 것과 비교했을 때)

 

 

시프트 연산 명령어

C의 <<, >> 연산자는 어셈블리에서는 시프트 명령어로 구현됩니다. 주로 곱셈/나눗셈, 비트 마스킹, 정렬 등에 활용됩니다.

명령어 설명 대응 C 연산자
shl / sal 산술적 왼쪽 시프트 (2의 배수 곱셈 효과) x << n
shr 논리적 오른쪽 시프트 (부호 없음, 나눗셈 효과) x >> n (signed)
sar 산술적 오른쪽 시프트 (부호를 유지하며 나눗셈) x >> n (unsigned)
sal $1, %rax   ; %rax = %rax * 2
sar $2, %rbx   ; %rbx를 4로 나누되 부호 유지

C에서의 `<<`, `>>` 연산은 어셈블리어에서도 직관적인 1:1 매핑으로 대응되며, 곱셈/나눗셈보다 빠른 연산이 필요한 경우 자주 활용됩니다.

 

추가로, 시프트 연산은 %cl 레지스터를 통해서도 시프트 양을 지정할 수 있습니다. 이때 %cl의 하위 비트만 유효하며, 나머지 상위 비트는 무시됩니다. 예를 들어, 64비트 연산에서는 %cl & 0x3F (최대 63) 범위로 제한됩니다.

 

 

단항 vs 이항 연산 구분

어셈블리 명령어는 피연산자의 수에 따라 단항(Unary)과 이항(Binary)으로 나뉩니다. 이 구분은 명령 해석 및 레지스터 사용을 이해할 때 매우 중요합니다.

  • 단항 연산: 하나의 피연산자만 사용. 결과는 자기 자신에 덮어씀.
    예: neg %eax , not %ebx
  • 이항 연산: 두 개의 피연산자를 사용. 목적지(dst)에 결과 저장.
    예: addl %eax, %ebx  → %ebx = %ebx + %eax

이런 구분은 C 코드 해석 시 연산의 구조와 번역 결과를 유추하는 데 큰 도움이 됩니다.

 

 

연산 명령어의 저장 규칙

모든 이항 연산 명령어는 다음과 같은 형태를 가집니다.

OP src, dst   ; dst = dst OP src

즉, 결과는 항상 목적지(dst)에 저장된다는 것을 기억해야 합니다. 이는 C코드 해석 시 매우 중요한 규칙이기도 합니다.

 

 

어셈블리 분석의 시작, 연산 명령어

연산 명령어들은 C 코드를 어셈블리로 바꿀 때 가장 기본이 되는 블록입니다. 컴파일러는 연산 순서, 타입, 최적화 전략에 따라 다양한 명령어로 번역할 수 있으므로, 이런 명령어들의 기본 동작을 알아두면 C 코드 → 어셈블리 해석에 큰 도움이 됩니다.

 

예를 들어, 아래와 같은 C 코드가 있다고 해보겠습니다.

int x = a + b;
int y = -x;
int z = x & y;

이 코드는 어셈블리어로 대략 다음과 같이 변환될 수 있습니다.

movl a(%rip), %eax     ; %eax = a
addl b(%rip), %eax     ; %eax = a + b
movl %eax, %ebx        ; %ebx = x (복사)
negl %ebx              ; %ebx = -x
andl %eax, %ebx        ; %ebx = x & (-x)

이처럼 C의 연산자들은 각각 대응되는 기계 명령어로 컴파일되며, 레지스터를 통해 연산이 수행됩니다. 특히 부호 반전(`-x`)은 negl, 비트 AND는 andl처럼 직관적인 1:1 매핑이 많다는 점을 기억해두면 좋습니다.

 

 

마치면서

기계 수준에서 산술 및 논리 연산은 다양한 명령어로 표현되는데요. 이러한 결과 저장 위치, 즉시값 처리, 산술 및 논리 연산의 활용 등을 이해하면 어셈블리 분석과 최적화의 기초를 다질 수 있습니다.

 

이어서 기계어의 진짜 핵심이라고 할 수 있는 메모리 접근과 함수 호출, 스택 프레임 등을 살펴볼 예정입니다. 다음 포스트에서는 그 중에서도 메모리 접근에 대해 다뤄보려고 하는데, 그에 앞서 이후의 모든 절에서 도움이 될 어셈블리 필수 배경 지식에 대해서 알아보겠습니다.

저작자표시 비영리 변경금지 (새창열림)

'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글

[CSAPP 3장 완전 정복] 3.4 메모리와 레지스터, 정보를 어떻게 읽고 쓸까?  (0) 2025.04.06
[CSAPP 3장 완전 정복] x86-64 어셈블리 필수 배경지식 핵심 정리  (0) 2025.04.06
[CSAPP 3장 완전 정복] 3.3 데이터는 메모리에 어떻게 저장될까?  (0) 2025.04.05
[CSAPP 3장 완전 정복] 3.2 어셈블리 명령어는 어떻게 저장될까?  (0) 2025.04.05
[CSAPP 3장 완전 정복] 3.1 어셈블리 언어와 친해지는 첫 걸음 + 추천 학습 순서  (0) 2025.04.05
'크래프톤 정글/컴퓨터구조(CSAPP)' 카테고리의 다른 글
  • [CSAPP 3장 완전 정복] 3.4 메모리와 레지스터, 정보를 어떻게 읽고 쓸까?
  • [CSAPP 3장 완전 정복] x86-64 어셈블리 필수 배경지식 핵심 정리
  • [CSAPP 3장 완전 정복] 3.3 데이터는 메모리에 어떻게 저장될까?
  • [CSAPP 3장 완전 정복] 3.2 어셈블리 명령어는 어떻게 저장될까?
그냥사람_
그냥사람_
IT 관련 포스팅을 합니다. 크래프톤 정글 8기 정경호
  • 그냥사람_
    그냥코딩
    그냥사람_
  • 전체
    오늘
    어제
    • 글 전체보기 N
      • 크래프톤 정글 N
        • 로드 투 정글(입학시험)
        • CS기초(키워드, 개념정리)
        • 컴퓨터구조(CSAPP)
        • Code 정글(C언어)
        • Equipped in 정글(나만무) N
        • 마이 정글(WIL, 에세이) N
      • 자료구조&알고리즘
        • 자료구조
        • 알고리즘
      • 일상
  • 블로그 메뉴

    • 홈
  • 링크

    • Github
  • hELLO· Designed By정상우.v4.10.3
그냥사람_
[CSAPP 3장 완전 정복] 3.5 기계 수준의 연산, 어떻게 작동할까?
상단으로

티스토리툴바