CMN
example
CMN은 Compare Negative의 약자입니다. 직역하면 “부정(음수) 비교” 명령어인데요, 더 쉽게 본질을 요약하면 “두 값을 더했을 때 결과가 어떻게 되는지(0인지, 음수인지 등)를 비교하는 명령어”입니다.
1. CMN 명령어의 핵심 개념: “비교를 위한 더하기”
보통 어셈블리어에서 값을 비교할 때 쓰는 CMP 명령어는 내부적으로 두 값을 빼기(Subtitle)해서 상태를 확인합니다. 반면, CMN 명령어는 내부적으로 두 값을 “더하기(Add)” 합니다.
- CMP X1, X2 ➡️ X1 - X2를 계산하여 플래그 변화를 확인 (두 값이 같은지, 누가 더 큰지 비교)
- CMN X1, X2 ➡️ X1 + X2를 계산하여 플래그 변화를 확인 (두 값을 더했을 때의 상태를 비교)
💡 수학적 원리 어떤 값 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 등)이 실행됩니다.
- Z (Zero) 플래그: 더한 결과가 정확히 0이 되면 1이 됩니다.
- 예: X0이 -5일 때 CMN X0, #5를 하면 결과가 0이 되므로 Z 플래그가 켜집니다. 바로 뒤에 BEQ(같으면 점프) 명령어를 써서 조건문을 처리할 수 있습니다.
- N (Negative) 플래그: 더한 결과가 음수이면 1이 됩니다.
- C (Carry) 플래그: 더했을 때 자리 올림(Overflow for Unsigned)이 발생하면 1이 됩니다.
- V (Overflow) 플래그: 부호 있는 정수 연산에서 표현 범위를 초과하는 오버플로우가 발생하면 1이 됩니다.
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까지 살펴보니 하드웨어 레벨에서 조건문을 처리하는 방식이 정말 흥미롭지요?