What does the 'TEST' instruction do
TL;DR
어셈블리어에서 TEST
명령어는 eax
의 값이 0이냐 아니냐를 판단하기 위해서 사용한다. 만약 eax
의 값이 0이라면 (zf
가 세팅되어) 뒤에 JE
나 JZ
명령어가 온다면 jump한다.
TEST 명령어
문제를 풀다가 언제 jump하는지 항상 헷갈려서 블로그에 정리하려고 한다..
아래는 예시 어셈블리어이다.
1 | .text:0000131E |
간단하다.
test eax, eax
에서 eax
가 0인지 판단하고, 만약 0이라면 zf
가 1로 세팅된다. jnz(=jump not zero)
명령어는 이름 그대로 0이 아닐 경우 jump하기 때문에 eax
가 0이라면 jump하지 않는다.
하지만 문제 풀 때 의외로 많이 헷갈렸으므로 이 로직을 조금 더 뜯어보자.
1.
1 | text:00001324 mov edx, [eax+38h] |
- 이 연산은
edx
와eax
주소에 값을 저장하는 연산이다. - 사용자 인풋은
eax
주소에 저장된다. bss영역 정의된 배열에 값을 쓰는데 어째선지 배열의 사이즈를 모르는 상황이다. edx
에 배열 밖의 값이 저장된다는 사실을 파악해보자.
2.
1 | .text:0000132A xor eax, 11h |
xor
연산을 진행한다.eax
가 0x11라면 0으로 초기화가 되겠고, 0이라면eax
에 0x11가 저장될 것 이다.- 앞 부분 분석을 해보면
eax
에 무조건 0x11을 넣고 싶어질 것이기 때문에 이 연산 값은 0이 되고eax
에 0이 담긴다.
3.
1 | .text:0000132D or eax, edx |
or
연산을 진행한다. 두 값 중 어느 하나라도 0이 아니면 0이 아닌 수가eax
에 담길 것이다.- 현재
eax
은 0으로 고정이므로edx
값에 집중하여 분석해보자. edx
가 0이라면?0 | 0 = 0
,eax
의 값은 0이 된다.edx
가 X라면?0 | X = X
,eax
의 값은 X이 된다.
4.
1 | .text:0000132F test eax, eax |
eax
가 0인지를 검사한다. 실제로eax
에 값을 쓰지는 않는다.eax
가 0인 경우:edx
의 값이 0인 경우eax
가 X인 경우:edx
의 값이 X인 경우
5.
1 | .text:00001331 jnz short loc_1347 |
jnz = jump not zero
eax
가 0이 아니면 jump한다.- 참고로
loc_1347
은 실행하고 싶은 로직이 아니다. - 결론적으로 jump를 하면 안되고,
eax
가 0이어야 한다.eax
가 0이려면edx
가 0이어야 한다. - overflow때문에
edx
에 값을 입력할 수 있지만 배열 크기 검사를 진행했기 때문에 값을 쓰면 안된다는 결론을 얻을 수 있다.