Я возиться с запуском старых программ для DOS в эмуляторе, и я дошел до того, что мне хотелось бы отследить стек программы.Тем не менее, я сталкиваюсь с проблемой, в частности, как обнаружить ближние и дальние вызовы.Некоторые предлоги:
- Рядом с
call
помещается только IP-адрес в стек, и ожидается, что он будет связан с ret
, который выдвигает только IP-адрес для возврата. - Far
call
помещает CS и IP в стек, и ожидается, что он будет соединен с retf
, который выдвигает CS и IP для возврата. - Нет способа узнатьявляется ли вызов ближним или дальним, за исключением того, что он знает, какой тип инструкции вызвал его или какой ответ он использует.
К счастью, за период, в который была разработана эта программа, BP-основанные на стеке фреймы были очень обычными, так что обход стека не кажется проблемой: я просто следую цепочке BP.К сожалению, получить CS и / или IP сложно, потому что, кажется, у меня нет никакого способа определить, является ли вызов ближним или дальним, глядя только на стек.
У меня есть метаданные о доступных функциях, поэтому я могу сказать, является ли функция ближним или дальним вызовом, если я уже знаю фактические CS и IP, но я не могу определить IP и CS, если я уже не знаю, является ли это дальним вызовомили около вызова.
Я добился небольшого успеха, просто угадав и проверил, приводит ли мое предположение к действительному поиску функции, но я думаю, что этот метод даст много ложных срабатываний,
Итак, мой вопрос таков: как отладчики эпохи DOS справились с этой проблемой и создали трассировки стеков?Есть какой-то алгоритм для этого я пропускаю, или они просто кодируют отладочную информацию в стеке?(Если это так, то мне придется придумать что-то еще.)