grdb не рабочие переменные - PullRequest
1 голос
/ 15 марта 2010

Я знаю, что это немного отстает, но я просто не могу понять это. Я отлаживаю это:

xor eax,eax

mov ah,[var1]
mov al,[var2]

call addition

stop: jmp stop

var1: db 5
var2: db 6

addition:
add ah,al
ret

числа, которые я нахожу по адресам var1 и var2, равны 0x0E и 0x07. Я знаю, что он не сегментирован, но это не повод для таких переходов, потому что вызов сложения работает просто отлично. Не могли бы вы объяснить мне, где моя ошибка?


Я вижу проблему, но пока не знаю, как ее исправить. Дело в том, что по какой-то причине указатель команды начинается с 0x100, а все сегменты регистрируются с 0x1628. Для обращения к инструкции используется комбинация, которую я предполагаю [cs: ip] (один из регистров сегмента и указатель инструкции точно). Смещение к var1 составляет 0x10 (вероятно, потому что с самого начала кода это 0x10-й байт по порядку), я попытался проверить память и что я получил:

1628:100 8 bytes
1628:108 8 bytes
1628:110 <- wtf? (assume another 8 bytes)
1628:118 ...

какие бы то ни было уловки в памяти [cs: var1] указывает где-то еще, чем в моем коде, где, вероятно, метка .data обычно будет обращаться к ds ... вероятно ... я не знаю, что предполагается быть в 1628: 10


Хорошо, я узнал, что вызвало задницу, и потратил на меня весь этот чертов день. описанное выше поведение просто правильно, код полностью функционален. что я не знал, так это то, что отладчик grdb по какой-то причине устанавливает начальный адрес на 0x100 ... решение состоит в том, чтобы вставить директиву ORG 0x100 в первую строку, и это все. код работал, потому что указатель инструкции имеет правильный адрес для первой инструкции и идет один за другим, но ваш ассемблер не знает, по какому эффективному адресу будет храниться ваша программа, поэтому он в значительной степени остается относительно первой строки кода, что означает все переменные (если не использовать метку для раздела данных) будут продолжать указывать, как если бы они начинались с 0x0. что, конечно, не будет работать с DOS. и grdb, очевидно, эмулирует некоторые функции DOS ... извините за язык, спасибо всем за усилия, надеюсь, это сэкономит кому-то время, если возникнет та же проблема ...

хе-хе .. по крайней мере теперь я знаю причину, по которой следует использовать раздел .data:))))

1 Ответ

2 голосов
/ 15 марта 2010

Предполагая, что это сборка x86, var1 и var2 должны находиться в разделе .data.


Объяснение: Я не собираюсь объяснять точно, как структурирован исполняемый файл (не говоря уже о том, что это зависит от платформы), но вот общее представление о том, почему вы делаете не работает.

Код сборки должен быть разделен на разделы данных в связи с тем, что каждый раздел данных напрямую (или почти напрямую) соответствует определенной части двоичного / исполняемого файла. Все глобальные переменные должны быть определены в разделах .data, поскольку они имеют соответствующее местоположение в двоичном файле, где находятся все глобальные данные.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...