смещение на 32 бита, ближний вызов, реальный режим

#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.