Дамп - Источник ошибки

Несмотря на то, что мы уже произвели перевод команды с языка машины на язык ассемблера, это пока не намного приблизило нас к отысканию самой ошибки. Нам известно лишь, какая команда программы выполнялась последней. Для того чтобы понять, почему выполнение такой на первый взгляд безобидной команды не было закончено, нужно найти соответствующее ей предложение в исходной программе на языке ассемблера. Как только это будет сделано, то, используя знание языка ассемблера и логики выполняемой программы, можно будет перейти к непосредственному определению - причины ошибки и ее устранению.

Итак, нам известен адрес искомой команды. Расположение же соответствующего предложения в исходной программе нам не известно. Вспомним, что значение счетчика размещения, отвечающее определенной команде программы на языке ассемблера, равно адресу этой команды относительно начала программы. Если бы нам удалось определить адрес первого байта программы непосредственно после загрузки ее в память, то мы бы смогли вычислить значение счетчика размещения, соответствующее искомому предложению в исходной программе.

Адресом точки входа (Entry Point Address — ЕРА) загрузочного модуля называется адрес первой выполняемой после загрузки команды. В данном случае для нас не существенно различие между адресом точки входа и адресом загрузки, т. е. адресом, по которому происходит загрузка первого байта модуля. В более сложных случаях эти адреса не совпадают, но описываемая ниже процедура может быть легко модифицирована применительно к ним.

Где именно следует искать адрес точки входа — зависит от операционной системы и типа дампа. На рис. 12.4 изображен дамп Системы 360, так называемый SYSTEM UTILITY DUMP. В нем значение ЕРА располагается в первой строке таблицы CDE (Contents Directory Entries).В этой таблице содержится описание содержимого всех областей памяти, запрашиваемых данным шагом задания. Нашему загрузочному модулю система присвоила имя ** GO. Адрес точки входа загрузочного модуля всегда помещается в первую строку CDE, которую следует искать в конце первой страницы дампа. Итак, в соответствующем месте первой строки мы находим предложение

ЕРА 06А810

Это и есть искомый адрес точки входа.

Графически рассматриваемая ситуация изображена на рис. 12.5. Адрес команды, при выполнении которой имел место особый случай, равен значению счетчика команд за вычетом длины команды. В данном случае ЕРА совпадает с адресом первого байта загрузочного модуля. Если адресацию вести, начиная с байта 0, то, очевидно

(PC)—2(ILC)=EPA+LOC

Итак, значение счетчика размещения, соответствующее команде исходной программы, при выполнении которой был зафиксирован особый случай, равно

LOC=(PC)—2(ILC) — ЕРА

Возвращаясь к нашему примеру, имеем

6 А8С8 = (PC) — 2( ILC)

Рис. 12.5. Взаимосвязь содержимого счетчика команд, адреса точки входа и счетчика размещения.

Из рис. 12.2 видно, что предложение, которому соответствует значение счетчика размещения В8, имеет вид

DIFLOOP L 10,NMBRS(9)

Именно эта команда загрузки вызвала особый случай.

Отметим, что, не изменяя значение счетчика команд, мы могли бы найти эту же команду по значению счетчика размещения, соответствующему следующей за ней команде. В нашем случае

 следующей команды

Команда, предшествующая той команде, значение счетчика размещения для которой равно ВС, и является искомой.

Описанная выше процедура поиска команды, при выполнении которой обнаружена ошибка, справедлива всегда, за исключением случая, когда искомая команда является командой перехода. Например, при попытке передачи управления по нечетному адресу фиксируется особый случай спецификации, 0С6. При этом PSW содержит адрес той команды, на которую мы пытались произвести переход, и не позволяет определить, где же находится сама команда перехода.

Совершенно аналогичная ситуация возникает при попытке передачи управления на команду из «чужой» области памяти или на команду с неверно заданным кодом операции. В любом случае для отыскания ошибки требуется ответить на вопрос, как же мы умудрились произвести подобный переход? Вообще наличие ошибок такого типа почти всегда свидетельствует о неверной загрузке базового регистра. Для отыскания самих ошибок достаточно проанализировать содержимое регистров и команды загрузки базового регистра, хотя это и требует определенных усилий.

 



 
Статьи раздела