При обращении мы видим некоторый интермодулярный вызов, например call dword ds:[004000238h]
или call dword ptr ds:_imp_atoi
.
Почему он использует сегмент данных вместо использования сегмента кода (CS
)?Почему мы используем DS для вызова процедур?
ответ
call dword ds:[004000238h]
является непрямыми рядом вызовов, он прочитал значение DWORD в 004000238h и использует его, чтобы сделать вызов.
Обратите внимание, что квадратные скобки и dword ptr
являются точками для определения типа инструкции.
Поскольку операнд инструкции является операндом памяти, то неявно используется для его чтения (с помощью дизассемблера, педантичного, показывающего его с синтаксисом переопределения сегмента).
Звонок находится рядом (дальние звонки в защищенном режиме редки и несут специальную семантику), поэтому текущее значение CS
не изменяется.
Можно сказать, что CS
неявно используется, поскольку вызов относится к текущему значению CS
.
Intel manual 3 описывает механизмы вызова в protected mode.
В качестве побочного примечания, даже для 32-разрядных систем сегментация эффективно отключена (все дескрипторы имеют нулевой уровень), поэтому вы можете забыть о регистрах селектора, но для TLS и SEH (которые обычно используют fs
/gs
регистры).
Почему нам нужна таблица адресов импорта даже в статических модулях связи в c. Я думаю, что IAT используется для динамического связывания –
@ user7445340 Трудно сказать без конкретного примера, но API Windows реализованы в основном в виде пользовательских пространственных DLL. В среде выполнения C все еще нужно загружать библиотеки, такие как 'user32' и' kernel32'. –