가장 최근의 연산 상태를 저장하는 1비트짜리 레지스터
산술연산에 의해 묵시적으로 결정된다.
CF: Carry flag. unsigned 연산 결과 MSB에 carry나 borrow가 발생하면 1.
ZF: Zero flag. 연산 결과가 0이면 1.
SF: Sign flag. 연산 결과가 음수면 1.
OF: Overflow flag. signed 연산 결과 오버플로우가 발생하면 1.
Example
cmpq b, a // a - b 연산으로 비교CF: a - b 연산 중 carry 발생 CF = 1
ZF: a - b == 0 ZF = 1
SF: a - b < 0 SF = 1
OF: (a>0 and b<0 and a-b<0) || (a<0 and b>0 and a-b>0) OF = 1
Test 연산
test 연산을 통해 condition code를 설정할 수 있다.
test b, aa&b연산 수행 condition code 설정, a&b 결과는 저장X
setX 명령
destination의 하위 바이트를 condition code의 조합 0과 1로 바꿈.
나머지 7 bytes는 변경되지 않음.
| setX | Condition | Desription |
|---|---|---|
| sete | ZF = 1 | 같다 / 0 |
| setne | ZF = 0 | 같지 않다 / !0 |
| sets | SF = 1 | 음수 |
| setns | SF = 0 | 음수 아님 |
| setg | ZF = 0 and SF = OF | 더 큼 (signed 비교) |
| setge | SF = OF | 크거나 같음 (signed 비교) |
| setl | SF != OF | 더 작음 (signed 비교) |
| setle | SF!=OF or ZF = 1 | 작거나 같음 (signed 비교) |
| seta | CF = 0 and ZF = 0 | 더 큼 (unsigned 비교) |
| setb | CF = 1 | 더 작음 (unsigned 비교) |
Example: setX 실습
xorq %rax, %rax subq $1, %rax cmpq $2, %rax setl %al movzblq %al, %eax
Instruction %rax SF CF OF ZF xorq %rax, %rax 0x0000 0000 0000 0000 0 0 0 1 subq $1, %rax 0xFFFF FFFF FFFF FFFF 1 1 0 0 cmpq $2, %rax 0xFFFF FFFF FFFF FFFF 1 1 0 0 setl %al 0xFFFF FFFF FFFF FF01 1 0 0 0 movzblq %al, %eax 0x0000 0000 0000 0001 1 0 0 0
jX 명령
condition code에 따라 코드의 다른 부분으로 점프함.
( = jump if X)
| jX | Condition | Description |
|---|---|---|
| jmp | 1 | 조건 없이 그냥 뜀 |
| je | ZF = 1 | 같거나 0이면 뜀 |
| jne | ZF = 0 | 같지 않거나 0이 아니면 뜀 |
| js | SF = 1 | 음수면 뜀 |
| jns | SF = 0 | 음수가 아니면 뜀 |
| jg | SF=OF and ZF = 0 | 더 크면 뜀 (signed 비교) |
| jge | SF=OF | 더 크거나 같으면 뜀 (signed 비교) |
| jl | SF != OF | 더 작으면 뜀 (signed 비교) |
| jle | SF != OF or ZF = 1 | 더 작거나 같으면 뜀 (signed 비교) |
| ja | CF = 0 and ZF = 0 | 더 크면 뜀 (unsigned 비교) |
| jb | CF = 1 | 더 작으면 뜀 (unsigned 비교) |
조건문에서 활용
if-else 문은 Goto code로도 표현할 수 있음.
//only if-else
long absdiff(long x, long y)
{
long result;
if (x > y) result = x - y;
else result = y - x;
return result;
}
//with goto
long absdiff_j(long x, long y)
{
long result;
if ntest = x <= y;
if (ntest) goto Else;
result = x - y;
goto Done;
Else:
result = y - x;
Done:
return result;
}
Example: condition branches
// if-else in C long absdiff(long x, long y) { long result; if (x > y) result = x-y; else result = y-x; return result; }
Register Use(s) %rdi Argument x %rsi Argument y %rax Return value //Assembly code absdiff: movq %rdi, %rax subq %rsi, %rax //result = x-y; movq %rsi, %rdx subq %rdi, %rdx //eval = y-x; cmpq %rsi, %rdi cmovle %rdx, %rax //if (x<=y) result = eval; ret* cmovX : 조건부 이동 명령
조건문은 항상 분기문으로 작성되지는 않는다.
최적화 된 형태로 작성함.
<참고자료>
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition
안성용, "시스템소프트웨어", 부산대학교