는 모든 레지스터 보존을위한 좋은 후보를합니다
no (e)ax -- Implicitly used in some instructions; Return value
no (e)dx -- edx:eax is implicity used in cdq, div, mul and in return values
(e)bx -- generic register, usable in 16-bit addressing modes (base)
(e)cx -- shift-counts, used in loop, rep
(e)si -- movs operations, usable in 16-bit addressing modes (index)
(e)di -- movs operations, usable in 16-bit addressing modes (index)
Must (e)bp -- frame pointer, usable in 16-bit addressing modes (base)
Must (e)sp -- stack pointer, not addressable in 8086 (other than push/pop)
테이블을 보면, 두 레지스터 보존 할 좋은 이유가 있고이 이유가 보존 될 수 없습니다 있습니다. 누산기 = (e) ax. 짧은 인코딩으로 인해 가장 자주 사용되는 레지스터입니다. SI, DI는 논리 레지스터 쌍을 만듭니다 - REP
MOVS 및 기타 문자열 연산에서 모두 휴지통입니다.
반호 평소/발신자 저장 패러다임에서 기본적으로 bx/cx가 si/di보다 선호되는 경우에만 토론이 진행됩니다. 다른 호출 규칙에서는 쓰레기 수있는 EDX, EAX 및 ECX 만 있습니다.
EBX에는 최신 코드 (예 : CMPXGH8B/CMPXGH16B)와 여전히 관련이있는 몇 가지 모호한 암시 적 사용이 있지만 32/64 비트 코드에서 가장 특수한 레지스터는 아닙니다.
EBX는 비 휘발성 레지스터가 아니라 EBX가 구체적으로 필요하기 때문에 EBX를 저장/복원해야하는 경우는 드물기 때문에 통화 보존 레지스터를 선택하는 것이 좋습니다. Brett Hale의 답변에 따르면, EBX는 ABI에서 필요로하는 전역 오프셋 테이블 (GOT) 포인터에 대한 좋은 선택입니다.
16 비트 모드에서 주소 지정 모드는 [BP|BX + DI|SI + disp8/disp16]
의 (모든 하위 집합으로) 제한되었으므로 BX는 확실히 특별합니다.
일부 컴파일러 (예 : Microsoft)는 프레임 포인터를 사용하지 않도록 설정할 수 있습니다.이 경우 ebp는 여분의 레지스터가되지만 피 호출자가 저장해야하는지 여부는 알 수 없습니다. – rcgldr
사실입니다. 그러나 디버그 (또는 레거시 타겟)에서 컴파일 할 때 서브 루틴이 bp를 쓰레트 수 있도록 허용하면 심각한 페널티가 발생할 수 있습니다. 더 나은 프로그래밍 패러다임은 bp를 입력 할 때 저장하고 종료 할 때 항상 호출하기 전에 저장하는 대신 저장하는 것입니다. –
언급 한 바와 같이, eax, ecx 및 edx는 호출자가 저장되는 경우 (필요한 경우) 나머지 ebp를 포함하여 레지스터가 저장되거나 수정되지 않습니다. 난 단지 프레임 포인터없이 푸시 ebp, 평소 mov ebp, esp 필요하지 않을 것이라고 지적했다. – rcgldr