Автор: wiki.rom.by , 12 февраля 2008
Содержимое данного поля является приватным и не предназначено для показа.

BBCode

  • HTML-теги не обрабатываются и показываются как обычный текст
  • You may use the following BBCode tags:
    • [align]
    • [b]
    • [code]
    • [color]
    • [font]
    • [hr]
    • [i]
    • [img]
    • [list]
    • [quote]
    • [s]
    • [size]
    • [spoiler]
    • [sub]
    • [sup]
    • [table]
    • [u]
    • [url]
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.

Материал из Wiki.


<!-- start content -->

Вопрос:


Очень часто, при просмотре биоса (original.bin), встречается следующий код:
Пример:
call 88BE
...
1. 88BE: push 0E000
2. 88C1: push 088CF
3. 88C4: push 0EC31
4. 88C7: push 0323C
5. 88CA: jmp 0F000:0EC30
6. 88CF: retn
Такие куски кода встречаются очень часто. Отличаются они только (как правило) строками 2 и 4. Я как понял, это вызов какой-то функции...
push 088CF - сохранение адреса для возврата

Вопрос: Как узнать где находится код этой функции...
где его искать? (в bootloader'e или в original.bin или еще где-то) и по какому смещению?

Ответ:


Биос в основном состоит из одного большого файла, который ложится на два сегмента E000 и F000.
Для того, чтобы вызвать подпрограмму, находящуюся в сегменте F000 (у нас $F) и имеющую инструкцию
ближнего возврата, из сегмента E000 (у нас обозначено $E), используют подобный способ.
Для этого необходимо в сегменте $F добавить две инструкции ближнего и дальнего возврата.

После дальнего перехода на вершине стека остается адрес процедуры, расположенной в $F.
Переход осуществляется с помощью retn в сегменте $F. После ближнего выхода из подпрограммы происходит переход на
инструкцию retf, адрес которой оказывается на вершине стека. Тогда происходит дальний возврат на адрес $E@@ret.

В самом деле, различаться будут только второй и четвертый push, поскольку в них содержится информация о ближнем адресе
вызова и адресе возврата. Сегмент $E и ближний адрес retf в сегменте $F - постоянные величины.

Этот пример можно найти везде, поскольку все приведенные адреса являются стандартными для всех биосов AWARD.
Потому, имея любой подобный биос и зная адреса, такой листинг можно получить за минуту. У меня получилось немного
громоздко, но, надеюсь, понятно.

Наш пример также показывает то, что биосы AWARD собираются из частей, написанных еще в 1992-1993 годах.
Подобного рода задержки после вывода в порт будут работать на машинах не старше 486, а выравнивания на 4 перед инструкциями
in и out также излишни.

Таким образом код вопроса можно прокомментировать так:


1. 88BE: push 0E000       //сегмент возврата (обычно текущий)
2. 88C1: push 088CF //адрес возврата в текущем сегменте (например E000:88CFh)
3. 88C4: push 0EC31 //retf
4. 88C7: push 0323C //адрес подпрограммы F000:323Ch
5. 88CA: jmp 0F000:0EC30 //переход в $F сегмент на команду retn (ближний возврат)
6. 88CF: retn

Объяснение взято отсюда: https://rom.by/forum/Что_означает_этот_кусок_кода_в_авардовсоком_биосе