TEST (x86 명령어)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
TEST는 x86 명령어 중 하나로, 플래그 레지스터의 값을 설정하는 데 사용된다. TEST 연산은 CF와 OF 플래그를 0으로 설정하고, SF, ZF, PF 플래그는 AND 연산 결과에 따라 설정된다. 주로 조건부 분기와 함께 사용되어 특정 레지스터의 값이 0인지 또는 음수인지 확인하는 데 활용된다. 예를 들어, 레지스터의 특정 비트가 설정되었는지 확인하거나, 16바이트 주소 정렬을 테스트하는 데 사용될 수 있다.
더 읽어볼만한 페이지
- X86 명령어 - 스트리밍 SIMD 확장
스트리밍 SIMD 확장(SSE)은 x86 아키텍처의 SIMD 명령어 집합으로, 128비트 XMM 레지스터를 사용하여 데이터 병렬 처리를 통해 성능을 향상시키며, 인텔 펜티엄 III 프로세서에 처음 도입되어 여러 후속 버전으로 발전했다. - X86 명령어 - SSE2
SSE2는 인텔이 개발한 x86 아키텍처의 SIMD 명령어 집합 확장으로, MMX 명령어의 정수 벡터 연산을 확장하고 XMM 레지스터를 사용하여 부동 소수점 연산 성능을 향상시키며, AMD64 아키텍처에서도 지원된다.
TEST (x86 명령어) | |
---|---|
명령어 개요 | |
동작 | |
연산 | 수행되는 연산은 피연산자1 AND 피연산자2. 결과는 버려지고, SF, ZF, PF 플래그가 설정됨. OF와 CF는 0으로 설정됨. AF는 정의되지 않음. |
지원되는 연산 크기 | |
크기 | 바이트 워드 더블워드 쿼드워드 (64비트 모드에서) |
피연산자 | |
피연산자 유형 | 레지스터 메모리 즉시값 (immediate) |
피연산자 수 | 2 |
플래그 | |
OF (오버플로 플래그) | 0 |
SF (부호 플래그) | 결과의 최상위 비트를 반영 |
ZF (제로 플래그) | 결과가 0이면 1, 아니면 0 |
AF (보조 캐리 플래그) | 정의되지 않음 |
PF (패리티 플래그) | 결과의 최하위 바이트에서 1의 개수가 짝수면 1, 홀수면 0 |
CF (캐리 플래그) | 0 |
보호 모드 예외 | |
#GP(0) | 유효하지 않은 메모리 주소에 접근하려고 시도한 경우 발생. |
#SS(0) | 유효하지 않은 스택 세그먼트에 접근하려고 시도한 경우 발생. |
#PF(오류 코드) | 페이지 폴트가 발생한 경우 발생. |
#AC(0) | 얼라인먼트 체크가 활성화되었고, 정렬되지 않은 메모리 주소에 접근하려고 시도한 경우 발생. |
실수 모드 예외 | |
#GP(0) | 유효하지 않은 메모리 주소에 접근하려고 시도한 경우 발생. |
#SS(0) | 유효하지 않은 스택 세그먼트에 접근하려고 시도한 경우 발생. |
가상 8086 모드 예외 | |
#GP(0) | 유효하지 않은 메모리 주소에 접근하려고 시도한 경우 발생. |
#SS(0) | 유효하지 않은 스택 세그먼트에 접근하려고 시도한 경우 발생. |
#PF(오류 코드) | 페이지 폴트가 발생한 경우 발생. |
#AC(0) | 얼라인먼트 체크가 활성화되었고, 정렬되지 않은 메모리 주소에 접근하려고 시도한 경우 발생. |
2. TEST 옵코드 변종
TEST 연산은 CF(Carry Flag)와 OF(Overflow Flag) 플래그를 0으로 설정한다.[1][2] SF(Sign Flag)는 AND 연산 결과의 최상위 비트(Most Significant Bit, MSB) 값으로 설정된다.[1][2] AND 연산 결과가 0이면 ZF(Zero Flag)는 1로 설정되고, 0이 아니면 0으로 설정된다.[1][2] PF(Parity Flag)는 결과의 최하위 바이트에 있는 1의 개수가 짝수이면 1로, 홀수이면 0으로 설정된다.[2] 이는 최하위 바이트의 비트들에 대한 XNOR 연산 결과와 같다.[1][2] AF(Auxiliary Carry Flag)의 값은 정의되지 않는다.[1][2]
TEST 명령어는 두 피연산자 간의 비트 단위 AND 연산을 수행한 결과에 따라 플래그 레지스터의 상태 플래그(주로 ZF, SF, PF)를 설정한다. 이 명령어 자체는 연산 결과를 피연산자에 저장하지 않지만, 설정된 플래그 값은 후속 조건 분기 명령어에서 프로그램의 실행 흐름을 결정하는 데 중요한 기준으로 사용된다.
3. 예시
예를 들어, 특정 레지스터의 값이 0인지, 음수인지, 또는 특정 비트 패턴(예: 메모리 주소 정렬 확인)을 가지고 있는지 등을 검사하는 데 활용될 수 있다. 구체적인 코드 예시와 작동 방식은 아래 하위 섹션들에서 자세히 설명한다.
3. 1. 조건부 분기
TEST 명령어는 두 피연산자 간의 비트 단위 AND 연산을 수행하고, 그 결과에 따라 플래그 레지스터의 상태 플래그(주로 ZF, SF, PF)를 설정한다. 연산 결과 자체는 피연산자에 저장되지 않으며, 주로 후속 조건 분기 명령어의 조건을 설정하는 데 사용된다.
다음은 `TEST` 명령어를 이용한 조건부 분기의 예시이다.
test cl, cl ; cl 레지스터의 값과 자기 자신을 AND 연산한다. 결과가 0이면 (즉, cl이 0이면) ZF를 1로 설정한다.
je 0x804f430 ; ZF가 1이면 (cl이 0이면) 0x804f430 주소로 점프한다.
위 코드는 `cl` 레지스터의 값이 0인지 검사한다. `test cl, cl`은 `cl`과 `cl`을 AND 연산하며, 결과가 0이 되는 유일한 경우는 `cl` 자체가 0일 때이다. 결과가 0이면 ZF(Zero Flag)가 1로 설정된다. 이어지는 `JE` (Jump if Equal) 명령어는 `ZF`가 1일 때 지정된 주소(`0x804f430`)로 분기한다. `JZ` (Jump if Zero) 명령어 역시 동일하게 작동한다.
test cl, cl ; cl == 0 이면 ZF를 1로 설정한다.
jnz 0x8004f430 ; ZF가 0이면 (cl이 0이 아니면) 0x8004f430 주소로 점프한다.
반대로 값이 0이 아닐 때 분기하려면 `JNZ` (Jump if Not Zero) 명령어를 사용한다. `test cl, cl` 실행 후 `cl`이 0이 아니면 `ZF`는 0으로 설정되고, `jnz` 명령어는 `ZF`가 0일 때 지정된 주소(`0x8004f430`)로 분기한다. `JNE` (Jump if Not Equal) 명령어 역시 동일하게 작동한다.
test eax, eax ; eax 레지스터의 값과 자기 자신을 AND 연산한다. 결과의 부호 비트가 1이면 (즉, 음수이면) SF를 1로 설정한다.
js error ; SF가 1이면 (eax가 음수이면) 'error' 레이블로 점프한다.
`test eax, eax`는 `eax` 레지스터의 부호를 검사하는 데 사용될 수 있다. AND 연산 결과의 최상위 비트(부호 비트)가 1이면 SF(Sign Flag)가 1로 설정된다. `JS` (Jump if Sign) 명령어는 `SF`가 1일 때, 즉 값이 음수일 때 지정된 레이블(`error`)로 분기한다.
test al, $0F ; al 레지스터의 하위 4비트와 00001111b를 AND 연산한다. 결과가 0이면 (즉, 하위 4비트가 모두 0이면) ZF를 1로 설정한다.
jnz @destination ; ZF가 0이면 (al의 하위 4비트 중 하나라도 1이면) @destination 레이블로 점프한다.
`TEST` 명령어는 특정 비트 마스크와의 AND 연산을 통해 원하는 비트들이 설정되어 있는지 확인하는 데 유용하다. 위 예시는 `al` 레지스터의 하위 4비트(`$0F`는 16진수 F, 2진수로는 `00001111`)가 모두 0인지 검사한다. 만약 `al`의 하위 4비트가 모두 0이라면 `al AND $0F`의 결과는 0이 되고 `ZF`는 1로 설정된다. 이 기법은 예를 들어 주소가 특정 값(여기서는 16)의 배수인지 확인하는 데 사용될 수 있다 (주소의 하위 4비트가 0인지 검사). `jnz`는 `ZF`가 0일 때, 즉 하위 4비트 중 1인 비트가 있어 16의 배수가 아닐 때 `@destination`으로 분기한다.
3. 2. 부호 확인
wikitext
test eax, eax ; eax < 0 (음수) 이면 SF를 1로 설정
js error ; SF == 1 이면 점프
위 코드는 eax 레지스터의 값을 자기 자신과 AND 연산하여 플래그 레지스터의 부호 플래그(SF) 상태를 변경한다. `TEST` 명령어는 연산 결과 자체를 저장하지 않고 플래그 값만 변경하는 특징이 있다.3. 3. 일반적인 응용
`TEST` 명령어는 특정 비트 패턴을 검사하거나 두 피연산자 간의 논리곱(AND) 연산 결과를 통해 플래그 레지스터의 상태를 변경하는 데 유용하게 사용된다. 연산 결과값 자체는 저장되지 않지만, 결과가 0인지(ZF 플래그), 음수인지(SF 플래그) 등을 판단하여 후속 조건부 분기 명령어의 실행 여부를 결정하는 데 쓰인다.
대표적인 응용 예시는 특정 값의 정렬 상태를 확인하는 것이다. 예를 들어, `test al, $0F` 명령어는 `al` 레지스터에 저장된 값이 16바이트 경계에 정렬되어 있는지 검사하는 데 사용될 수 있다. 이 명령어는 `al` 레지스터의 값과 16진수 값 $0F (2진수로 `00001111`) 사이의 논리곱(AND) 연산을 수행한다. 만약 `al`의 하위 4비트가 모두 0이라면 (즉, `al` 값이 16의 배수라면) 연산 결과는 0이 되고, 플래그 레지스터의 ZF(Zero Flag)가 1로 설정된다.
이어서 `jnz @destination` 명령어를 사용하면, ZF가 0일 경우 (즉, `test al, $0F`의 결과가 0이 아닐 경우, `al` 값이 16의 배수가 아닐 경우) `@destination`이라는 레이블로 프로그램 흐름을 이동시킨다. `jnz`는 'Jump if Not Zero'의 약자이다. 이를 통해 특정 조건(예: 주소 정렬 불일치)에 따라 다른 코드 경로를 실행할 수 있다.
참조
[1]
웹사이트
Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z
https://www.intel.co[...]
2019-12-21
[2]
웹인용
Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z
http://www.intel.com[...]
2013-07-18
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com