CMPS - DS:(E/R)SI에 있는 src 문자열과 ES:(E/R)DI에 있는 dest 문자열을 비교한다. 보통 REP 접두어와 같이 사용하여, CX 개만큼의 원소를 비교한다. 이때 DF 플래그가 1이면 역방향으로 진행하며 비교한다. 예제로 Linux 커널의 arch/x86_64/boot/video.S 에 있는 ati_test 를 참고.
예) CMPSB
예) CMPSW
예) CMPSD
예) CMPSQ
CMPSD/CMPSS - 배정도/단정도 부동소수점 실수 두 개를 비교. CMPSD는 64bit 버전이고 CMPSS는 32bit 버전임.
dest(첫 번째 operand)와 src(두 번째 operand)의 값을 comparison-predicate(세 번째 operand)가 지정하는 연산을 이용하여 비교한다.
다음과 같이 작동한다.
OP[] = {EQ, LT, LE, UNORD, NEQ, NLT, NLE, ORD}
if (dest[63:0] OP[comparison-predicate] src[63:0])
dest[63:0] = ffffffffffffffff
else
dest[63:0] = 0000000000000000 // dest[127:64] unchanged
위에서 UNORD는 dest 나 src 중 하나 이상이 NaN일 때 true이고, ORD는 dest 나 src 중 어느 하나도 NaN이 아닐 때 true이다.
예) CMPSD/CMPSS xmm1, xmm2/m64, imm8
예) CMPEQSD/CMPLTSD/CMPLESD/CMPUNORDSD/CMPNEQSD/CMPNLTSD/
CMPNLESD/CMPORDSD xmm1, xmm2
CMPXCHG/CMPXCHG8B/CMPXCHG16B - 비교 직후 값을 바꾼다. 구체적으로 다음과 같은 일을 한다.
if (accumulator == dest) {
zf = 1; dest = src;
} else {
zf = 0; accumulator = dest;
}
여기서 cmpxchg dest, src 를 사용하는 경우 accumulator는 AL/AX/EAX/RAX 이다.
cmpxchg8b dest 를 사용하는 경우 accumulator는 EDX:EAX이고 src는 ECX:EBX이다.
cmpxchg16b dest 를 사용하는 경우 accumulator는 RDX:RAX이고 src는 RCX:RBX이다.
LOCK prefix와 함께 사용하면 원자적으로 실행(atomic execution)된다.
Linux 커널 소스의 include/asm-x86_64/system.h 에서 cmpxchg()와 __cmpxchg() 를 참고하라.
예) cmpxchg r/m, r
예) cmpxchg8b m64
예) cmpxchg16b m128
COMISD/COMISS - 배정도/단정도 부동소수점 실수 값을 비교하여 EFLAGS 를 세팅해 준다. COMISD는 64비트 버전이고, COMISS는 32비트 버전이다.
첫 번째 operand와 두 번째 operand를 비교한 결과에 따라 ZF,PF,CF 에 들어오는 값이 다음과 같이 된다.
1) UNORDERED이면(즉, 둘 중 하나 이상이 NaN이면) 1,1,1
2) GREATER_THAN이면 0,0,0
3) LESS_THAN이면 0,0,1
4) EQUAL이면 1,0,0
단, 둘 중 하나가 SNaN 또는 QNaN이면 Invalid Numeric Exception이 발생한다.
CPUID - CPU에 대한 정보를 돌려준다. EAX 에 어떤 값이 들어있느냐에 따라 EAX, EBX, ECX, EDX에 각종 정보를 돌려준다.
CPUID 가 돌려주는 정보들은 다음과 같다.
- CPU 버전, 모델, 시리얼번호
- Cache와 TLB
- MONITOR/MWAIT
- Thermal & Power 매니지먼트
- 퍼포먼스
- Signature 및 Brand string
- Virtual/physical adress size
또한 instruction 수행을 serialize(직렬화)하는 데 CPUID 가 쓰인다. 즉, CPUID 인스트럭션 전에 나오는 인스트럭션에 의한 플래그/레지스터/메모리 수정이 다 끝난 다음에야 CPUID 다음에 나오는 인스트럭션이 수행된다.
사용 예를 보려면 Linux 커널의 arch/x86_64 또는 include/asm-x86_64 에서 "grep -R cpuid ." 를 사용해 보라.
예) CPUID
예) comisd/comiss xmm1, xmm2/m64
CVTDQ2PD - 부호 있는 doubleword 정수 배열을 배정도 부동소수점 실수 배열로 바꾼다.
CVTDQ2PS - 부호 있는 doubleword 정수 배열을 단정도 부동소수점 실수 배열로 바꾼다.
CVTPD2DQ - 배정도 부동소수점 실수 배열을 부호 있는 doubleword 정수 배열로 바꾼다.
CVTPD2PI - 배정도 부동소수점 실수 배열을 MMX 레지스터에 부호 있는 doubleword 정수로 바꾸어 넣는다.
CVTPD2PS - 배정도 부동소수점 실수 배열을 단정도 부동소수점 실수 배열로 바꾼다.
예) CMPSB
예) CMPSW
예) CMPSD
예) CMPSQ
CMPSD/CMPSS - 배정도/단정도 부동소수점 실수 두 개를 비교. CMPSD는 64bit 버전이고 CMPSS는 32bit 버전임.
dest(첫 번째 operand)와 src(두 번째 operand)의 값을 comparison-predicate(세 번째 operand)가 지정하는 연산을 이용하여 비교한다.
다음과 같이 작동한다.
OP[] = {EQ, LT, LE, UNORD, NEQ, NLT, NLE, ORD}
if (dest[63:0] OP[comparison-predicate] src[63:0])
dest[63:0] = ffffffffffffffff
else
dest[63:0] = 0000000000000000 // dest[127:64] unchanged
위에서 UNORD는 dest 나 src 중 하나 이상이 NaN일 때 true이고, ORD는 dest 나 src 중 어느 하나도 NaN이 아닐 때 true이다.
예) CMPSD/CMPSS xmm1, xmm2/m64, imm8
예) CMPEQSD/CMPLTSD/CMPLESD/CMPUNORDSD/CMPNEQSD/CMPNLTSD/
CMPNLESD/CMPORDSD xmm1, xmm2
CMPXCHG/CMPXCHG8B/CMPXCHG16B - 비교 직후 값을 바꾼다. 구체적으로 다음과 같은 일을 한다.
if (accumulator == dest) {
zf = 1; dest = src;
} else {
zf = 0; accumulator = dest;
}
여기서 cmpxchg dest, src 를 사용하는 경우 accumulator는 AL/AX/EAX/RAX 이다.
cmpxchg8b dest 를 사용하는 경우 accumulator는 EDX:EAX이고 src는 ECX:EBX이다.
cmpxchg16b dest 를 사용하는 경우 accumulator는 RDX:RAX이고 src는 RCX:RBX이다.
LOCK prefix와 함께 사용하면 원자적으로 실행(atomic execution)된다.
Linux 커널 소스의 include/asm-x86_64/system.h 에서 cmpxchg()와 __cmpxchg() 를 참고하라.
예) cmpxchg r/m, r
예) cmpxchg8b m64
예) cmpxchg16b m128
COMISD/COMISS - 배정도/단정도 부동소수점 실수 값을 비교하여 EFLAGS 를 세팅해 준다. COMISD는 64비트 버전이고, COMISS는 32비트 버전이다.
첫 번째 operand와 두 번째 operand를 비교한 결과에 따라 ZF,PF,CF 에 들어오는 값이 다음과 같이 된다.
1) UNORDERED이면(즉, 둘 중 하나 이상이 NaN이면) 1,1,1
2) GREATER_THAN이면 0,0,0
3) LESS_THAN이면 0,0,1
4) EQUAL이면 1,0,0
단, 둘 중 하나가 SNaN 또는 QNaN이면 Invalid Numeric Exception이 발생한다.
CPUID - CPU에 대한 정보를 돌려준다. EAX 에 어떤 값이 들어있느냐에 따라 EAX, EBX, ECX, EDX에 각종 정보를 돌려준다.
CPUID 가 돌려주는 정보들은 다음과 같다.
- CPU 버전, 모델, 시리얼번호
- Cache와 TLB
- MONITOR/MWAIT
- Thermal & Power 매니지먼트
- 퍼포먼스
- Signature 및 Brand string
- Virtual/physical adress size
또한 instruction 수행을 serialize(직렬화)하는 데 CPUID 가 쓰인다. 즉, CPUID 인스트럭션 전에 나오는 인스트럭션에 의한 플래그/레지스터/메모리 수정이 다 끝난 다음에야 CPUID 다음에 나오는 인스트럭션이 수행된다.
사용 예를 보려면 Linux 커널의 arch/x86_64 또는 include/asm-x86_64 에서 "grep -R cpuid ." 를 사용해 보라.
예) CPUID
예) comisd/comiss xmm1, xmm2/m64
CVTDQ2PD - 부호 있는 doubleword 정수 배열을 배정도 부동소수점 실수 배열로 바꾼다.
CVTDQ2PS - 부호 있는 doubleword 정수 배열을 단정도 부동소수점 실수 배열로 바꾼다.
CVTPD2DQ - 배정도 부동소수점 실수 배열을 부호 있는 doubleword 정수 배열로 바꾼다.
CVTPD2PI - 배정도 부동소수점 실수 배열을 MMX 레지스터에 부호 있는 doubleword 정수로 바꾸어 넣는다.
CVTPD2PS - 배정도 부동소수점 실수 배열을 단정도 부동소수점 실수 배열로 바꾼다.
댓글 0
.