Skip to the content.

CMN

example

CMN은 Compare Negative의 약자입니다. 직역하면 “부정(음수) 비교” 명령어인데요, 더 쉽게 본질을 요약하면 “두 값을 더했을 때 결과가 어떻게 되는지(0인지, 음수인지 등)를 비교하는 명령어”입니다.


1. CMN 명령어의 핵심 개념: “비교를 위한 더하기”

보통 어셈블리어에서 값을 비교할 때 쓰는 CMP 명령어는 내부적으로 두 값을 빼기(Subtitle)해서 상태를 확인합니다. 반면, CMN 명령어는 내부적으로 두 값을 “더하기(Add)” 합니다.

💡 수학적 원리 어떤 값 A에 B를 더하는 것(A + B)은, A에서 -B(음수 B)를 빼는 것(A - (-B))과 수학적으로 완벽히 같습니다. 그래서 이름이 Compare Negative(음수와 비교)가 된 것입니다.


2. 왜 CMP가 있는데 굳이 CMN을 따로 쓰나요?

가장 큰 이유는 컴퓨터(CPU) 메모리와 명령어 크기의 한계 때문이며, 이를 통해 코드 효율성을 극대화하기 위해서입니다. 만약 우리가 C언어로 다음과 같은 조건문을 짰다고 가정해 봅시다.

if (x == -5) { … }

컴퓨터가 이를 처리하려면 원래 x - (-5)를 해야 하므로, 레지스터에 -5라는 숫자를 만들어서 빼야 합니다. 하지만 CPU 명령어 내부에 ‘음수 상수’를 직접 집어넣는 것은 하드웨어 구조상 까다롭거나 불가능할 때가 많습니다. 이때 CMN을 사용하면 하드웨어는 아주 영리하게 작동합니다.

CMN X0, #5 ; X0에 5를 더해본다 (결과적으로 X0 - (-5)를 한 것과 같음!)

레지스터에 복잡하게 음수를 만들 필요 없이, 양수 5를 명령어에 바로 넣고 내부적으로 덧셈 연산기를 돌려서 x가 -5였는지 단번에 알아낼 수 있게 됩니다. 즉, 코드가 더 짧아지고 실행 속도가 빨라집니다.

3. 작동 방식과 상태 플래그(Flags) 변환

CMN은 두 값을 더한 뒤, 그 결과에 따라 CPU의 상태 레지스터(NZCV 플래그)를 업데이트합니다. 이 플래그를 보고 바로 다음에 오는 조건부 분기문(BEQ, BMI 등)이 실행됩니다.


4. 실제 어셈블리 코드 예시

이해를 돕기 위해 ARM64 어셈블리 기준으로 어떻게 쓰이는지 보여드릴게요.

; 상황: 레지스터 X0에 들어있는 값이 -10인지 확인하고 싶다!

CMN X0, #10 ; X0 + 10 을 계산합니다. (플래그만 바꾸고 X0 값은 유지됨) BEQ match_label ; 만약 X0이 -10이었다면 결과가 0이 되어 Z플래그가 켜지므로 match_label로 점프!

; (X0이 -10이 아닐 때 실행될 코드) …

match_label: ; (X0이 -10일 때 실행될 코드) …


📌 요약 비교

앞서 배우신 CMGE와 이번 CMN을 비교하면 어셈블리 명령어를 이해하는 눈이 훨씬 넓어지실 겁니다.

명령어 본질적인 내부 연산 결과 반영 방식 주요 목적
CMGE 두 값의 대소 비교 (>=) 레지스터에 비트 마스크(0xFF.. 또는 0x00..) 저장 SIMD 병렬 처리 및 if문 없는 조건부 필터링
CMN 두 값의 덧셈 연산 (+) CPU 상태 플래그(Z, N, C, V) 변경 음수 비교 및 상수 연산 최적화 (일반 분기문용)

CMGE와 CMN까지 살펴보니 하드웨어 레벨에서 조건문을 처리하는 방식이 정말 흥미롭지요?