ESI 및 EDI 레지스터의 목적?


답변:


77

DI / SI (또는 1985 년에 ASM을 배우지 않은 경우 확장 된 대응) 로만 할 수있는 몇 가지 작업이 있습니다 . 이들 중

REP STOSB
REP MOVSB
REP SCASB

각각 반복 (= 대량) 저장,로드 및 스캔 작업입니다. 당신이하는 일은 하나 또는 두 피연산자를 가리 키도록 SI 및 / 또는 DI를 설정하고 아마도 CX에 카운트를 넣은 다음 찢어 버리십시오. 이들은 한 번에 많은 바이트에서 작동하는 작업이며 CPU를 자동으로 설정합니다. 루프를 명시 적으로 코딩하지 않기 때문에 수작업으로 코딩 한 루프보다 더 효율적으로 (보통) 작업을 수행합니다.

궁금한 점이있는 경우를 대비하여 작업을 설정하는 방법에 따라 반복 저장은 값 0을 큰 연속 메모리 블록에 펀칭하는 것과 같이 간단 할 수 있습니다. MOVSB는 한 버퍼에서 다른 버퍼로 데이터를 복사하는 데 사용됩니다. SCASB는 일부 검색 기준과 일치하는 바이트를 찾는 데 사용됩니다 (동등성에 대해서만 검색하는지 또는 무엇을 찾을 수 있는지 확실하지 않습니다. :))

그게 바로 그 regs의 대부분입니다.


7
과거의 최적화 팁 : 담당자 stosw은 훨씬 빨리보다 렙 stosb 는 것을, 사용을하려고하는지와이 두 바이트 맞는 복사 그렇다면, 대신에 당신의 손에 최적화 된 16 비트의 x86 어셈블리 코드에서 ...
알렉산더

88

SI= 소스 색인
DI= 목적지 색인

다른 사람들이 지적했듯이 그들은 문자열 명령어와 함께 특별한 용도를 가지고 있습니다. 리얼 모드 프로그래밍의 경우, ES세그먼트 레지스터와 함께 사용되어야 DI하고 DSSI같이

movsb  es:di, ds:si

SI 및 DI는 범용 인덱스 레지스터로도 사용할 수 있습니다. 예를 들어, C소스 코드

srcp [srcidx++] = argv [j];

컴파일

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

경우는 ebp+12포함 argv, ebx이다 j, 그리고 edi있다 srcidx. 세 번째 명령어는 edi4로 다중화를 사용 하고 ebp오프셋을 0x54 (의 위치 srcp)로 추가합니다. 주소 주위의 대괄호는 간접적임을 나타냅니다.


나는 그것을보고 위치를 기억하지만, 수는 없지만 확인한다 대부분의 그것의, 그리고 (슬라이드 17) 기타 :

AX= 누산기
DX= 더블 워드 누산기
CX= 카운터
BX= 기본 레지스터

범용 레지스터처럼 보이지만 (예기치 않게?) 그중 하나를 사용하지만 어떤 것을 암시 적으로 사용하는 명령어가 많이 있습니다.


37

ESI가 가리키는 메모리에서 EDI가 가리키는 메모리로 데이터를 효율적으로 복사하는 MOVSB ​​및 MOVSW와 같은 Opcode. 그러므로,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

12

다른 답변에서 언급 된 문자열 연산 (MOVS / INS / STOS / CMPS / SCASB / W / D / Q 등) 외에도 암시 적으로 사용하는 "현대적인"x86 어셈블리 명령이 더 있다는 것을 추가하고 싶습니다. 최소 EDI / RDI :

SSE2 MASKMOVDQU(및 곧 출시 될 AVX VMASKMOVDQU) 명령어는 XMM 레지스터의 바이트를 EDI / RDI가 가리키는 메모리에 선택적으로 기록합니다.


6

대량 연산에 사용되는 레지스터 외에도 32 비트 호출 규칙에서 함수 호출 (호출 보존)을 통해 보존되는 속성에 유용합니다. ESI, EDI, EBX, EBP, ESP는 통화 보존되는 반면 EAX, ECX 및 EDX는 통화 보존되지 않습니다. 호출 보존 레지스터는 C 라이브러리 함수에 의해 존중되며 해당 값은 C 라이브러리 함수 호출을 통해 유지됩니다.

그의 어셈블리 언어 책에있는 Jeff Duntemann에는 명령 줄 인수를 인쇄하기위한 예제 어셈블리 코드가 있습니다. 이 코드는 esi 및 edi를 사용하여 카운터를 저장합니다. C 라이브러리 함수 printf에 의해 변경되지 않습니다. eax, ecx, edx와 같은 다른 레지스터의 경우 C 라이브러리 함수에서 사용되지 않는다는 보장이 없습니다.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

섹션 12.8 C가 명령 줄 인수를 보는 방법을 참조하십시오.

64 비트 호출 규칙은 32 비트 호출 규칙과 다르며 이러한 레지스터가 호출 보존 여부는 확실하지 않습니다.


나는 대부분의 사람들이 "휘발성"/ "비 휘발성"이라고 부르는 것을 "신성"이라고 부르는 것을 "신성"이라고 부르는 것을 들어 본 적이 없다. 나는 "call-preserved"/ "call-clobbered"를 좋아하는데, 그것이 그들이 실제로 어디에서나 구원 받았다는 것을 의미하지 않기 때문입니다. 어쨌든 ESI / RSI 및 EDI / RDI는 x86-64 System V ABI에서 호출 보존되지 않습니다.
Peter Cordes

또한 EBP 및 ESP를 일반적인 32 비트 호출 규칙에 보존 된 호출로 나열하는 것을 잊었습니다.
Peter Cordes

1
어쨌든, 그것은 꽤 좋은 지적입니다. 실제 코드에서는 명령에 대해 특별하기 때문에 호출 관례 이유에 따라 EDI / ESI를 선택할 가능성이 더 큽니다.
Peter Cordes

나는 통화 보존을 좋아합니다. 나는 똑같이 대답을 업데이트했습니다. 검토해 주셔서 감사합니다.
제이 라즈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.