컴퓨터 프로그램에서 조건문은 프로그램의 흐름을 제어하는 데 필수적인 요소입니다. 이러한 조건문이 기계어 수준에서는 어떻게 구현되는지 살펴보겠습니다.
무조건 분기: jmp 명령어
jmp 명령어는 프로그램의 실행 흐름을 지정된 위치로 강제로 이동시키는 데 사용됩니다. 이 명령어는 다음과 같은 형태로 사용될 수 있습니다:
jmp <주소>: 프로그램 카운터(PC)를 즉시 <주소>로 변경하여 해당 위치부터 실행을 재개합니다.jmp 5: 상수값 5로 직접 분기합니다.jmp eax:eax레지스터에 저장된 주소로 분기합니다.jmp [999]: 메모리 주소 999번지에 저장된 값을 주소로 사용하여 분기합니다.jmp NEXT:NEXT라는 레이블(이름표)이 붙은 위치로 분기합니다.
예시:
100: mov eax, 7
104: mov ebx, 6
108: jmp 116 ; 116번지로 무조건 이동
112: mov ecx, ebx ; 이 코드는 실행되지 않음
116: mov ecx, eax ; eax의 값(7)을 ecx에 저장
코드의 시작 주소가 변경될 경우, 절대 주소를 직접 사용하는 것은 문제가 될 수 있습니다. 이럴 때 레이블을 사용하면 주소 변경에 유연하게 대처할 수 있습니다.
mov eax, 7
mov ebx, 6
jmp NEXT ; NEXT 레이블로 이동
mov ecx, ebx ; 이 코드는 실행되지 않음
NEXT: ; 레이블 정의 (이름은 자유롭게 지정 가능)
mov ecx, eax ; eax의 값(7)을 ecx에 저장
조건부 분기 명령어
조건부 분기 명령어는 특정 조건이 만족될 때만 실행 흐름을 변경합니다. 이러한 명령어들은 주로 cmp 명령어와 함께 사용되어 두 피연산자를 비교한 후, 그 결과를 바탕으로 분기 여부를 결정합니다.
| 기능 | 어셈블리 명령어 | 설명 |
|---|---|---|
| 동일할 때 점프 | je <주소> |
Jump if Equal (a == b 일 때 점프) |
| 동일하지 않을 때 점프 | jne <주소> |
Jump if Not Equal (a != b 일 때 점프) |
| 더 클 때 점프 | jg <주소> |
Jump if Greater |
| 크거나 같을 때 점프 | jge <주소> |
Jump if Greater or Equal |
| 더 작을 때 점프 | jl <주소> |
Jump if Less |
| 작거나 같을 때 점프 | jle <주소> |
Jump if Less or Equal |
cmp a, b 명령어는 a와 b를 비교합니다. 이 비교는 실제로 a - b 연산을 수행하며, 그 결과는 프로그램 상태 워드(PSW) 레지스터의 특정 플래그(flag)에 기록됩니다.
cmp 명령어의 내부 동작 원리
cmp 명령어는 두 피연산자를 빼서 그 결과를 플래그 레지스터에 반영합니다. 주요 플래그는 다음과 같습니다:
- CF (Carry Flag, 캐리 플래그): 뺄셈에서 빌림(borrow)이 발생하면 1이 됩니다.
- ZF (Zero Flag, 제로 플래그): 연산 결과가 0이면 1이 됩니다.
- SF (Sign Flag, 부호 플래그): 연산 결과가 음수이면 1이 됩니다.
- OF (Overflow Flag, 오버플로우 플래그): 부호 있는 정수 연산에서 결과가 표현 범위를 벗어나면 1이 됩니다.
이 플래그들을 사용하여 조건부 점프가 결정됩니다:
| 기능 | 어셈블리 명령어 | 설명 (플래그 조건) | 플래그 |
|---|---|---|---|
| 동일할 때 점프 | je <주소> |
a == b 일 때 점프 | ZF == 1 |
| 동일하지 않을 때 점프 | jne <주소> |
a != b 일 때 점프 | ZF == 0 |
| 더 클 때 점프 | jg <주소> |
a > b 일 때 점프 (부호 있는 비교) | ZF == 0 && SF == OF |
| 크거나 같을 때 점프 | jge <주소> |
a >= b 일 때 점프 (부호 있는 비교) | SF == OF |
| 더 작을 때 점프 | jl <주소> |
a < b 일 때 점프 (부호 있는 비교) | SF != OF |
| 작거나 같을 때 점프 | jle <주소> |
a <= b 일 때 점프 (부호 있는 비교) | SF != OF || ZF == 1 |
C 언어의 if-else 문을 어셈블리로 변환하는 예시:
// if (a > b) { c = a; } else { c = b; }
mov eax, 7 ; a를 eax에 로드
mov ebx, 6 ; b를 ebx에 로드
cmp eax, ebx ; eax와 ebx를 비교 (eax - ebx)
jg NEXT ; 결과가 양수 (eax > ebx)이면 NEXT로 점프
mov ecx, ebx ; 그렇지 않으면 c = b (ecx = ebx)
jmp END ; END로 무조건 점프 (NEXT 코드를 건너뛰기 위해)
NEXT:
mov ecx, eax ; a > b 조건이 참이면 c = a (ecx = eax)
END:
; 프로그램 계속 진행