프로세서 상태 (x86-64)
현재 실행 중인 프로그램에 관한 정보를 포함한다
cf) Flag -- binary 1 or 0 임 !!
CF : 캐리 플래그
ZF : 제로 플래그
SF : 부호 플래그
OF : overflow 플래그
ex. ZF = 1 이면 계산값이 0 이라는 뜻
condition codes(암묵적 설정)
- cf (unsigned)
- sf (signed) : 이게 올라가면 이 숫자는 음수인거임
- zf
- of (signed)
ex. addq Src, Dest 은 t = a+b 와 같은 명령 수행
cf 는 msb가 캐리 플래그로 설정되어 연산 결과가 표현 가능한 범위 벗어나는지 여부를
zf는 t == 0 이면
sf는 t<0 이면
of 는 오버플로우의 발생 여부.
만약 a b 모두 양수이고 연산 결과t 가 음수일 때
혹은
만약 a b 모두 음수이고 연산 결과 t 가 양수 일때
-> 이 두 조건 중 하나라도 만족하면 OF 가 설정된다.
cmp a, b (sub와 비슷)
b-a 임
연산을 하긴 하는데 b의 값을 바꾸진 않음 걍 연산해본다고
음 그니까 표현을 해보자면
b = b-a
이게 아니라
b-a
이 연산만 한다 이소리임
test a,b
b&a 임(and 랑 같음)
가장 common use:
test %rX,%rX
%rX 를 0과 비교하기 위해 이렇게 씀.
두번째로 common한 use:
test %rX, %rY
ex. rx : 0001
ry: 0001
=> 0001 로, 1인게 겹치는 부분이 존재함
rx : 0110
ry:0001
=> 0000 로, 1인게 겹치는 부분이 존재하지 않아요
jX 명령어는 조건부(조건문->Flag 를 봄)로 코드의 다른 부분으로 이동한다
조건 코드에 따라 다양한 조건에 따라 분기할 수 있다.
setX 명령어는 조건 코드를 기반으로 대상의 최하위 바이트를 0 또는 1로 설정한다.
남은 7바이트는 변경되지 않는다.
즉, 조건 코드에 따라 대상 레지스터의 가장 낮은 바이트만 설정된다.
(%al, %r8b,etc.)
cmpq %rsi,%rdi # compare x:y
setg %al # set when >
movzbl %al, %eax. ret #zero rest of %rax
이 명령어 시퀀스는 다음과 같은 동작을 수행
cmpq %rsi, %rdi:
%rsi와 %rdi 레지스터의 값을 비교.
이 명령어는 두 레지스터의 값을 비교하고, 그 결과에 따라 조건 코드를 설정
여기서는 %rdi가 %rsi보다 크면 setg 명령어를 통해 조건 코드를 설정할 것임 .
setg %al:
조건 코드가 "greater than"을 나타내는 경우(%rdi > %rsi),
%al 레지스터의 가장 낮은 바이트를 1로 설정합니다.
즉, %al에 1을 저장합니다.
movzbl %al, %eax:
%al 레지스터의 값을 %eax 레지스터로 확장.
%eax의 상위 바이트는 0으로 설정된다.
ret: 함수를 종료하고 리턴.
이것은 보통 두 값을 비교하고 그 결과를 확인하여 어떤 동작을 취할지를 결정하는 비교 및 조건 분기 프로그래밍에서 사용됩니다.
cf) movzbl: al 남기고 나머지 다 0으로
.. 왜 ?
: 옛날 계산값들이 혹시 남아있을 수 있어서 그냥 0으로 초기화.
조건부 분기에는 goto 문이 사용될 수 있다.
C 언어에서는 goto 문을 사용하여 레이블로 지정된 위치로 이동할 수 있음
ex:
if (condition) {
goto label;
}
// Some other code here
label:
// Code to be executed when condition is true
위의 코드에서, condition이 참일 때 goto 문을 통해 label로 분기된다.
그러면 label에 지정된 코드가 실행됨.
그러나 주의해야 할 점은 goto 문을 남용하면 코드가 복잡해지고 이해하기 어려워질 수 있다는 것=.=
일반적으로 구조화된 프로그래밍 방식을 선호하며, goto 문은 특정한 상황에서만 사용하는 것이 좋아여
conditional move instructions (최대한 jump 안하고 동일한 효과 내려고 만든거임)
조건부 이동을 사용하는 것은 분기 명령어보다 선호되는 경우가 있어요
~
조건부 이동 명령어는 테스트를 수행하고 그 결과에 따라 값을 이동하는데 사용됨.
이 명령어들은 "if (TesT) Dest<-Src" 패턴을 따름
이러한 조건부 이동 명령어는 1995년 이후의 x86 프로세서에서 지원됩니다.
GCC 컴파일러는 가능한 경우 이러한 명령어를 사용하려고 시도함
왜냐하면 조건부 이동은 분기 명령어에 비해 매우 유용할 뿐만 아니라 실행 중인 파이프라인의 명령어 흐름을 방해하지 않기 때문입니다.(그래서 안전한 경우에 씀, 안되면 기존의 jump..)
분기 명령어는 명령어 파이프라인을 중단시키고 예측 분기 실패로 인한 오버헤드가 발생할 수 있는데 ??ㅠ.ㅠ
조건부 이동은 제어 전송을 필요로하지 않기 때문에 이러한 오버헤드가 없음
따라서 코드 실행의 유연성을 높이고 프로세서 파이프라인을 더 효율적으로 사용할 수 있습니다.
분기 명령어는 조건에 따라 프로그램의 흐름을 변경하는 명령어입니다. 예를 들어, if 문이나 while 루프와 같은 제어 구조를 구현하는 데 사용됩니다. 분기 명령어는 조건을 평가하고 조건이 참이면 다른 코드 블록으로 점프하고, 거짓이면 다음 명령어로 이동합니다. 대표적인 분기 명령어로는 jmp, je (jump if equal), jne (jump if not equal) 등이 있습니다.
조건부 이동 명령어는 조건을 평가하고 해당 조건이 참이면 값을 이동시키는 명령어입니다. 조건부 이동 명령어는 조건을 평가한 후 목적지 레지스터에 값을 이동하거나, 또는 목적지 메모리 위치에 값을 저장합니다. 예를 들어, cmovl (conditional move if less), cmovge (conditional move if greater or equal) 등이 있습니다. 이 명령어들은 조건이 충족되지 않으면 아무 작업도 수행하지 않고 그대로 진행합니다.
조건부 이동 명령어는 일반적으로 분기 명령어보다 실행 효율이 더 높고 파이프라인의 효율성을 유지하는 데 더 좋습니다.