#x86 #call #real-mode
#x86 #вызов #реальный режим
Вопрос:
Предположим, у нас есть почти относительная инструкция вызова x86.
E8 offset // offset from the next instruction
Размер смещения определяется текущим размером операнда.
В 32-битном защищенном режиме:
E8 rel32 // target 32bit address = add_32bit(eip, rel32)
66 E8 rel16 // target 32bit address = zero_extend_32bit(add_16bit(ip, rel16))
В 64-битном режиме:
E8 rel32 // target 64bit address = add_64bit(rip, sign_extend_64bit(rel32))
66 E8 rel16 // target 64bit address = zero_extend_64bit(add_16bit(ip, rel16))
В реальном режиме:
E8 rel16 // target 16bit address = add_16bit(ip, rel16)
Чего я не понимаю, так это того, что произойдет, если у нас будет 32-битное смещение в реальном режиме? Один из возможных способов:
66 E8 rel32 // target 16bit address = truncate_16bit(add_32bit(eip, rel32))
Таким образом, в этом случае ip будет загружен с целевым 16-битным адресом. Но другой возможный сценарий заключается в том, что eip будет загружен с целевым 32-битным адресом, и если он равен > 0xFFFF, будет сгенерирована ошибка защиты.
Так что же происходит с 66 E8 rel32
в реальном режиме? Спасибо.
Комментарии:
1. Я бы предположил, что IP-адрес усекается до 16 бит после операции. Это не изменит CS, поэтому я почти уверен, что на самом деле это не полезный, но интересный вопрос о том, что происходит. Это достаточно неясно, чтобы стоило проверить реальное оборудование, а не только эмулируемый процессор в BOCHS, если только кто-то не уверен в правильном ответе без проверки.
2. Таким образом, это означает, что мы можем предположить, что rel32 сокращен до rel16 и добавлен к ip.
3. Да, если мое предположение верно, то
66
префикс размера операнда не влияет на относительные (прямые) ближние переходы / вызовы в 16-битном режиме, кроме увеличения длины инструкции на 3 байта.4. Спасибо за ответ. Это действительно помогает мне.
5. Предполагается, что относительный 32-битный скачок, превышающий предел сегмента CS , вызывает ошибку GP. В реальном режиме сегмент CS имеет ограничение 0xffff, поэтому, если ваша цель находится за его пределами, это вызовет ошибку GP в соответствии со ссылкой на набор команд . С учетом сказанного, можно изменить предел регистра CS таким образом, чтобы он был равен 0xffffffff. Это называется большим нереальным режимом . Если в этом режиме относительный 32-битный вызов не вызовет GP, поскольку весь диапазон от 0x0 до 0xffffffff находится в пределах ограничения сегмента CS.