`testl` eax와 eax?
어셈블리를 이해하려고합니다.
다음과 같은 어셈블리는 testl라인에 관심이 있습니다.
000319df 8b4508 movl 0x08(%ebp), %eax
000319e2 8b4004 movl 0x04(%eax), %eax
000319e5 85c0 testl %eax, %eax
000319e7 7407 je 0x000319f0
와 testl사이의 요점을 이해하려고합니다 . 나는이 코드가 중요하지 않다고 생각합니다. 테스트 자체를 이해하려고 노력하고 있습니다. 가치가 항상 사실이 아닙니까?%eax%eax
eax0 이상 인지 또는 이하 인지 테스트합니다 . 이 경우 점프 eax가 0 이면 점프가 수행됩니다 .
의미는 test인수를 함께 AND하는 것이며 결과가 0인지 확인하는 것입니다. 따라서이 코드는 EAX가 0인지 여부를 테스트합니다. je0이면 점프합니다.
BTW, 이것은 cmp eax, 0컴파일러가 일반적으로 이런 식으로하는 이유 보다 작은 명령을 생성합니다 .
테스트 명령어는 피연산자간에 논리 AND 연산을 수행하지만 결과를 레지스터에 다시 쓰지 않습니다. 플래그 만 업데이트됩니다.
테스트 eax 예제에서 eax는 eax가 0이면 zero flag를 설정하고, 가장 높은 비트가 설정되면 sign-flag와 다른 플래그도 설정합니다.
제로 플래그가 설정되어 있으면 Jump if Equal (je) 명령이 점프합니다.
코드를 다음과 같이 더 읽기 쉬운 코드로 변환 할 수 있습니다.
cmp eax, 0
je somewhere
그것은 동일한 기능을 가지고 있지만 몇 바이트 더 많은 코드 공간이 필요합니다. 이것이 컴파일러가 비교 대신 테스트를 수행 한 이유입니다.
test처럼 and그것은 단지 수정되지 않은 모두의 입력을 떠나, FLAGS를 기록 제외. 두 개의 서로 다른 입력을 사용 하면 일부 비트가 모두 0인지 또는 하나 이상의 비트가 설정되어 있는지 테스트하는 데 유용합니다. (예를 들어 test al, 3EAX가 4의 배수이면 ZF를 설정합니다 (따라서 낮은 2 비트가 모두 0으로 설정 됨).
test eax,eax모든 플래그를 정확히 같은 방식으로 설정하는 cmp eax, 0것을 :
- CF와 OF가 지워짐 (AND / TEST는 항상 그렇게합니다; 0을 빼면 캐리가 생성되지 않습니다)
- EAX의 값에 따른 ZF, SF 및 PF. (
a = a&a = a-0).
(평소와 같이 PF 는 하위 8 비트에 따라서 만 설정됩니다 )
더 이상 사용되지 않는 AF (ASCII / BCD 명령어에서 사용하는 보조 캐리 플래그)는 제외합니다. 테스트는 정의되지 않은 상태 로 두지 만 CMP는 "결과에 따라"설정합니다 . 0을 빼면 4 ~ 5 번째 비트에서 캐리가 생성되지 않으므로 CMP는 항상 AF를 지워야합니다.
테스트는 더 작고 (즉시 없음) 때로는 더 빠릅니다 (CMP보다 더 많은 경우 더 많은 CPU에서 비교 및 분기 uop로 매크로 퓨즈를 사용할 수 있음). 이는 test레지스터를 0과 비교하기 위해 선호되는 관용구를 만듭니다 . cmp reg,0시맨틱 의미에 관계없이 사용할 수 있도록 들여다 보는 구멍 최적화입니다 .
즉시 0으로 CMP를 사용하는 유일한 이유는 메모리 피연산자와 비교할 때입니다. 예를 들어, cmpb $0, (%esi)암시 적 길이 C 스타일 문자열의 끝에서 종료 0 바이트를 확인합니다.
AVX512F 추가kortestw k1, k2 및 AVX512DQ / BW (Skylake-X이지만 KNL 제외) add ktestb/w/d/q k1, k2는 AVX512 마스크 레지스터 (k0..k7)에서 작동하지만 test정수 OR또는 AND명령어 와 같은 방식으로 일반 FLAGS를 설정 합니다. (SSE4 ptest또는 SSE 와 같은 정렬 ucomiss: SIMD 도메인에 입력되어 정수 FLAGS가됩니다.)
kortestw k1,k1분기의 관용적 인 방법 / cmovcc / setcc SSE / AVX2 교체 AVX512 비교 결과에 기초하여 (v)pmovmskb/ps/pd+ test또는 cmp.
jzvs.의 사용은 je혼란 스러울 수 있습니다.
jz그리고 je말 그대로 동일한 명령이다 , 기계 코드에서 동일한 연산 코드를 즉. 그것들은 같은 일을하지만 인간에게는 다른 의미 론적 의미를 가지고 있습니다 . 디스어셈블러 (및 일반적으로 컴파일러의 asm 출력)는 하나만 사용하므로 시맨틱 구별이 사라집니다.
cmpsub두 입력이 같을 때 (즉, 빼기 결과가 0 인 경우) ZF 를 설정합니다. je(동일한 경우 점프)는 의미 적으로 관련된 동의어입니다.
test %eax,%eax/ and %eax,%eax는 결과가 0 일 때 ZF를 다시 설정하지만 "같음"테스트는 없습니다. 테스트 후 ZF는 두 피연산자가 같은지 여부를 알려주지 않습니다. 따라서 jz(0 인 경우 점프)은 의미 적으로 관련된 동의어입니다.
이 코드 스 니펫은 아마도 일부 구조체 나 객체에 대한 포인터가 제공된 서브 루틴에서 나온 것입니다. 두 번째 줄은 그 포인터를 역 참조하여 그 자체에서 포인터 또는 아마도 int를 가져와 두 번째 멤버 (오프셋 +4)로 저장합니다. 세 번째 및 네 번째 줄은이 값을 0으로 테스트하고 (포인터 인 경우 NULL), 0 인 경우 다음 몇 가지 작업 (표시되지 않음)을 건너 뜁니다.
The test for zero sometimes is coded as a compare to an immediate literal zero value, but the compiler (or human?) who wrote this might have thought a testl op would run faster - taking into consideration all the modern CPU stuff like pipelining and register renaming. It's from the same bag of tricks that holds the idea of clearing a register with XOR EAX,EAX (which i saw on someone's license plate in Colorado!) rather than the obvious but maybe slower MOV EAX, #0 (i use an older notation).
In asm, like perl, TMTOWTDI.
If eax is zero it will perform the conditional jump, otherwise it will continue execution at 319e9
In some programs they can be used to check for a buffer overflow. At the very top of the allocated space a 0 is placed. After inputting data into the stack, it looks for the 0 at the very beginning of the allocated space to make sure the allocated space is not overflowed.
It was used in the stack0 exercise of exploits-exercises to check if it was overflowed and if there wasnt and there was a zero there, it would display "Try again"
0x080483f4 <main+0>: push ebp
0x080483f5 <main+1>: mov ebp,esp
0x080483f7 <main+3>: and esp,0xfffffff0
0x080483fa <main+6>: sub esp,0x60
0x080483fd <main+9>: mov DWORD PTR [esp+0x5c],0x0 ;puts a zero on stack
0x08048405 <main+17>: lea eax,[esp+0x1c]
0x08048409 <main+21>: mov DWORD PTR [esp],eax
0x0804840c <main+24>: call 0x804830c <gets@plt>
0x08048411 <main+29>: mov eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>: test eax,eax ; checks if its zero
0x08048417 <main+35>: je 0x8048427 <main+51>
0x08048419 <main+37>: mov DWORD PTR [esp],0x8048500
0x08048420 <main+44>: call 0x804832c <puts@plt>
0x08048425 <main+49>: jmp 0x8048433 <main+63>
0x08048427 <main+51>: mov DWORD PTR [esp],0x8048529
0x0804842e <main+58>: call 0x804832c <puts@plt>
0x08048433 <main+63>: leave
0x08048434 <main+64>: ret
we could see the jg,jle If testl %edx,%edx. jle .L3we could easy find jleis suit (SF^OF)|ZF,if %edx is zero ,ZF=1,but if %edx is not zero and is -1,after the testl ,the OF=0,and the SF =1,so the flag =true,that implement jump .sorry ,my English is poor
참고URL : https://stackoverflow.com/questions/147173/testl-eax-against-eax
'Programing' 카테고리의 다른 글
| 전체 심볼릭 링크 경로를 보는 방법 (0) | 2020.07.27 |
|---|---|
| .htaccess RewriteRule이 작동하지 않는 방법 (0) | 2020.07.27 |
| 오류에서 localhost를 해제하는 방법 : EADDRINUSE 듣기 (0) | 2020.07.26 |
| Java에서 문자열을 동일한 길이의 하위 문자열로 분할 (0) | 2020.07.26 |
| SQL에서 GROUP BY와 ORDER BY의 차이점은 무엇입니까 (0) | 2020.07.26 |