Является ли ESP универсальным, как EAX?

В архитектуре x86, что можно сделать с EAX но не с ESP? Забывать о push а также pop а также call,

1 ответ

Решение

ESP неявно используется прерываниями. В современных ОС это относится только к стеку ядра, а не к стеку пользовательского пространства. Код ядра всегда должен поддерживать корректность ESP при включении прерываний и предполагать, что пространство под ним закрывается после каждой инструкции.

Основное (единственное?) Асинхронное использование ESP в пользовательском пространстве - это обработчики сигналов, поэтому процесс без обработчиков сигналов не должен иметь никакого асинхронного использования ESP. (Вы могли бы даже разработать новый ABI для ядра, чтобы доставлять сигналы, которые не заставляли использовать ESP).

Таким образом, код пользовательского пространства может в некоторых случаях избежать использования ESP в качестве 8-го регистра GP в критическом цикле, который в противном случае должен что-то пролить, но, как указывается в этой статье, отладка становится менее удобной в Windows, где SEH хочет найти действительный стек. Используйте регистр MMX или XMM для сохранения / восстановления ESP, поскольку статическое хранилище не будет поточно-ориентированным, а стек недоступен (проблема с курицей / яйцом). Те же аргументы в теории применимы к использованию RSP в 64-битном коде, но 15 регистров, отличных от RSP, и гарантированная поддержка SSE2 делают это крайне маловероятным.

Все остальное в этом ответе в равной степени относится к RSP в 64-битном режиме.


ESP ограничения как операнд регистра GP в asm / машинном коде

Есть только одна вещь, которую ESP не может сделать, что может любой другой регистр: ESP не может быть индексным регистром в режиме адресации.

mov  edx, [esp + eax*4]        ; legal
mov  edx, [eax + esp*4]        ; not encodeable

mov  edx, [eax + esp]          ; assemblers will encode this with esp as the base reg, since neither reg is scaled.

Если я правильно помню, это единственный случай, когда ESP просто не доступен в качестве операнда. Другим частным случаем является то, что ESP в качестве базового регистра всегда требуется байт SIB, даже если индекс отсутствует:

mov  edx, [eax]          ; 2 bytes: opcode + ModRM
mov  edx, [ebp]          ; 3 bytes: opcode + ModRM + disp8=0  (the other addressing-mode limitation, ebp/rbp and r13 as a base reg needs a displacement; the mode+M encoding that would mean this actually mean something else)
mov  edx, [esp]          ; 3 bytes: opcode + ModRM + SIB

mov  edx, [ebp + 4]      ; 3 bytes: opcode + ModRM + disp8
mov  edx, [esp + 4]      ; 4 bytes: opcode + ModRM + SIB + disp8

mov  edx, [ebp + 4 + eax]   ; 4 bytes: opcode + ModRM + SIB + disp8
mov  edx, [esp + 4 + eax]   ; 4 bytes: opcode + ModRM + SIB + disp8

Стоит также отметить, что в EAX есть много особенностей, даже по сравнению с другими регистрами, такими как ECX. Например, он неявно используется с stos, cdq и как операнд для mul (и этот список не является исчерпывающим). Существует также 1-байтовая кодировка для xchg eax, reg (отлично подходит для кода гольф, но не для производительности!), а также для обычной операции ALU с imm32 (например, add eax, imm32 против add r/m32, imm32). (Посмотрите эти инструкции ALU онлайн или оригинальный PDF-файл справочного руководства Intel - ссылки см. В вики-теге x86.)

EBX является единственным из 8 основных регистров общего назначения, который не является "специальным" или неявно используется какими-либо общими инструкциями. Для получения дополнительной информации о регистрах x86 и о том, откуда их имена / традиционное использование, см. http://www.swansontec.com/sregisters.html

Другие вопросы по тегам