오퍼랜드 [ 크래프톤 정글 17일차 ]

jinsung·2025년 5월 29일

크래프톤 정글 9기

목록 보기
15/59

지금 우리는 컴퓨터 시스템 책의 3장을 딥다이브 중인데요.

3장의 목표는

C가 컴파일러와 어셈블러를 통해 "어셈블리 및 기계어 코드"로 변환되는 과정을 이해하기

입니다. 왜 어셈블리 및 기계어 코드를 이해하는 것이 중요한 이유는 다음과 같습니다.

  • 성능 분석 및 최적화 시 중요한 힌트를 얻을 수 있고,

  • 디버깅, 보안 취약점 분석 (예: 버퍼 오버플로우)에도 필수적이다.

그 변환과정 중에 어셈블리어가 있는데

기계어에 비해 어셈블리는 조금 더 인간 친화적으로 작성되어 있으므로 그래도 소스코드를 분석하고 읽을 수 있어요.

이번에는 어셈블리어를 읽는 방법을 공부하는 과정에서 "오퍼랜드" 가 뭔지 설명하려 해요.

1. 오퍼랜드란?

우선 핵심부터 말할게요 오퍼랜드는

연산을 수행할 소스 값과, 그 결과를 저장할 목적지의 위치

컴퓨터는 캐싱을 위해 메모리를 자주 이동시키면서 저장하는데요.

자세한건 제가 적어둔 거있으니까 한 번 읽어보세요.

오퍼랜드는 "메모리의 위치" 혹은 "소스 값" 이예요.

간단하게 코드 예시를 볼게요.

대부분의 인스트럭션 ( 컴퓨터가 실행할 수 있는 기본 명령 단위 )은 하나 이상의 오퍼랜드를 가지는데

빨간 밑줄을 쳐놓은 부분이 인스트럭션이고
파란 동그라미가 오퍼랜드 입니다.

어떤 명령어를 실행할 때,

어떤 주소에 넣어야 할지,
어떤 값을 계산해야 할지 명시해줘야 하잖아요?

그게 오퍼랜드예요!

2. 오퍼랜드의 타입

오퍼랜드는 총 3가지의 타입이 있는데요.

  • 상수타입 (Immediate , 즉시 값 )
  • 레지스터 값
  • 메모리에서 가져오는 값

이렇게 3개가 있어요. 각각 어떻게 표현하는지 살펴볼게요.

Address    Value
0x100      0xFF
0x104      0xAB
0x108      0x13
0x10C      0x11

%rax = 0x100
%rcx = 0x1
%rdx = 0x3

$0x100 = ?

상수 타입

상수 타입은 앞에 $를 붙여서 사용합니다.

$0x100 의 값은 뭘까요?
0xFF 일까요?

$0x100은 그냥 0x100 입니다.
주소도 아닙니다.

그냥 0x100 이라는 값이예요.

그래서 "즉시값"이라고도 부릅니다. 즉시 사용하는 값이요.

레지스터 타입

Address    Value
0x100      0xFF
0x104      0xAB
0x108      0x13
0x10C      0x11

%rax = 0x100
%rcx = 0x1
%rdx = 0x3

%rcx = ?

%rax 는 특정 메모리 주소 (Address) 가 아닌 마치 변수처럼 직접 레지스터의 이름을 적어두었는데요.

x86-64 에서는 정해진 16개의 범용 레지스터가 있기 때문에 해당 이름을 변수로 생각해주시면 감사하겠습니다.

이렇게 오퍼랜드가 레지스터의 값을 가리키고 있는걸 "레지스터 타입" 이라고 합니다.

레지스터 타입을 작성했을 경우는

레지스터 가 가지고 있는 값이 그냥 나와요

%rcx = 0x100 이 나오게 됩니다.

메모리 주소 타입

Address    Value
0x100      0xFF
0x104      0xAB
0x108      0x13
0x10C      0x11

%rax = 0x100
%rcx = 0x1
%rdx = 0x3

0x100 = ?
(%rax) = ?

메모리 주소 타입은 해당 메모리에서 값을 가져오는 걸 얘기해요.

0x100 은 주소 값 이고 앞에 상수타입 $ 가 붙지 않았으니까 해당 주소에 있는 값을 가져오라는 것으로 해석됩니다.

그래서 0x100 = 0xFF

(%rax) 는 레지스터타입을 괄호로 감싸주었네요. 이것도 마찬가지로 "레지스터가 갖고 있는 값의 주소로 가서 값을 가져와라"는 뜻입니다.

레지스터 타입 값 계산하기

Address    Value
0x100      0xFF
0x104      0xAB
0x108      0x13
0x10C      0x11

%rax = 0x100
%rcx = 0x1
%rdx = 0x3

4(%rax) = 0xAB
9(%rax,%rdx) = 0x11
(%rax,%rdx,4) = 0x11

이건 좀 헷갈려 미리 답을 달아두었어요.

만약 () 앞에 숫자가 붙어있다면 괄호안에 있는 값에 해당 숫자를 더해주면 돼요.

  • %rax 의 값은 0x100 + 4 = 0x104 , (0x104) 와 같으므로
  • 4(%rax) = 0xAB 가 됩니다.

(%rax,%rdx) 처럼 여러개가 있는 경우라면 두 개를 더 해주면 돼요!

  • %rax = 0x100 , %rdx = 0x3 이므로 더하면 0x104네요!
  • 근데 앞에 9가 붙었어요 9를 더해서
  • 9 + 0x100 + 0x3 = 0x10c = 0x11 입니다!

(%rax,%rdx,4) 처럼 마지막에 상수가있는 경우는 곱셈을 해주면 됩니다!

  • (%rax + %rdx * 4 )
  • = (0x100 + 0x3 * 4 )
  • = (0x100 + 0xc)
  • = 0x10c = 0x11

짜잔

예시를 들어서 보니까 훨씬 쉬워졌어요.

정리

  1. 오퍼랜드는 연산을 수행할 소스값과 주소를 저장할 목적지이다!
  2. 오퍼랜드는 상수,레지스터,메모리주소 총 3가지 타입이 있다!
  3. 오퍼랜드의 주소 값 더하는건 지피티한테 문제 만들어달라해서 연습해보자!

1개의 댓글

comment-user-thumbnail
2025년 5월 29일

에버랜드 보내줘요...ㅜㅜ

답글 달기