четверг, 21 мая 2009 г.

Опять игры с сегментами

При попытках понять как работают компиляторы, отладчики и прочая сказочная живность начинаешь обнаруживать интересные вещи. И становится не понятно, то ли это ошибки компиляторов и отладчиков, то ли это их фишки :)
Итак ближе к монитору. Новая серия "Hello World". Нас ждут невероятные приключения в дебрях кода супер программы.

Итак нового мутанта в студию:

Казалось бы, что тут особенного?! В принципе так оно и есть, но вот TASM и MASM по разному компилируют данную программу, но это в принципе не самая интересная особенность. Интересно, то, что компилятор TASM инициализирует не правильным значением регистр SP (указатель стека). Происходит это видимо потому, что мы указали тип выравнивания для стека DWORD, что привело к тому, что стек начинается не на границе параграфа. Соответственно часть стека потерялась, то есть она ни когда не будет использована. Похоже что это глюк TASM. Смотрим следующий скриншот, и погружаемся в глубокую медитацию.

Замечаем, что отладчик использует стек отлаживаемой программы для своих целей. Это может ему дорого стать :) если со стеком что-нибудь сотворить. Но об этом в следующей серии нашего сериала.
Выпуск серий чуть опаздывает от моего изучения ассемблера и исследования поведения компиляторов и отладчиков.
И так, на что следует обратить внимание на скриншоте. Во первых, TASM абсолютно правильно, скомпилил EXE файл, в соответствии с теми атрибутами выравнивания сегментов что мы задавали, НО вот при загрузке в память программы регистр SP получил не правильное значение, и указывает не на дно стека (вернее не на перове слово за концом стека), а указывает на начало параграфа, считая что стек начинается на границе парагарфа, но у нас он не начинается на границе параграфа! Вот такой вот глюк, ну или фишка :). Второе это, то, что отладчик помещает на дно стека два нулевых байта в начале своей работы. Зачем он это делает? Не знаю... Видимо ему это нужно :)
Из всего этого вывод, что работу компиляторов надо проверять :) Не факт, что они создадут, то что мы задумывали :)
Теперь посмотрим как MASM откомпилил нашу прогу:

MASM просто забил на наш атрибут DWORD для выравнивания стека. Он все равно расположил его, как видим, на границе параграфа. В принципе и правильно сделал :) видимо не захотел мучится с высчитыванием смещения дна стека :)
Смотрим все под отладчиком:

Видим, что сейчас с SP все в порядке.

Теперь повторим наш эксперимент с установкой значений SS и SP вручную. Изучаем внимательно текст программы:

И смотрим какой EXE создал TASM:

Стоит обратить внимание даже на визуальное представление стека. Далее как водится загоняем прогу в отладчик. Далее приведен скриншот еще до выполнения первой команды.

Как видим, наш стек девственно чист, и не осквернен отладчиком :), так как он полагает что стек находится в другом месте :), в конце PSP. Теперь выполним все команды до mov ax,13D5, т.е. команды которые заносят в регистры SS и SP правильные значения.

Теперь, как видно, все в порядке, но в стеке много "мусора", который занес туда отладчик.
MASM тоже отранслировал эту программу. Размер совпал с размером проги отранслированной TASM.

Комментариев нет: