Смешивание ассемблера и программ на С - PullRequest
1 голос
/ 05 ноября 2010

Я использую программу начального загрузчика, которая находится на Ассемблере, и я часто вызываю функцию C, чтобы ПОСЫЛАТЬ и ПОЛУЧАТЬ Символ одновременно.Контроллер, который я использую, кажется, имеет только 3 регистра общего назначения, которые он часто использует.Кроме того, я храню некоторые байты в фиксированных местах ОЗУ.

ТАК, мой вопрос: перезаписывает ли функция С эти места в ОЗУ, которые были определены в сборке?

Я выполняю PUSH и PULL для соответствующих регистров перед тем, как приступить к этим функциям C и после них.

Ответы [ 3 ]

1 голос
/ 05 ноября 2010

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

Вам необходимо выяснить, как был скомпилирован код C (с какой настройкой Calling Convention).Обратите внимание, что это также зависит от архитектуры.Сводку различных соглашений о вызовах и описание каждого из них можно найти в Википедии здесь:

http://en.wikipedia.org/wiki/Calling_convention

http://en.wikipedia.org/wiki/X86_calling_conventions

На x86, cdecl иstdcall - самые популярные соглашения.cdecl означает, что ваш код ASM должен выполнить очистку, в то время как stdcall говорит, что вызываемая функция отвечает за это.Если у вас есть исходный код для функции C, я бы предложил передать необходимые флаги компилятору, чтобы сделать его условием «Callee cleanup» (обычно это stdcall, но также можно использовать safecall и fastcall), что означает, что вы можете безопасно вызывать Cфункция, не беспокоясь о повреждении реестра.

1 голос
/ 05 ноября 2010

Если я правильно понимаю ваш вопрос, вы обеспокоены тем, что места ОЗУ, используемые в модуле сборки, перекрываются с некоторой переменной, объявленной в модуле C. Вы можете проверить вывод файла списка вашим компоновщиком, чтобы определить, так ли это. Файл списка компоновщиков покажет все адреса ОЗУ, используемые вашими модулями Си, которые вы можете сравнить с фиксированными расположениями ОЗУ, используемыми в модуле сборки.

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

1 голос
/ 05 ноября 2010

Пока вы сохраняете предыдущие значения в стеке при выполнении вызовов c, все будет в порядке. Просто убедитесь, что вы помещаете в стек перед вызовом и выталкиваете из стека после возврата.

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