Зачем нужен ассемблер. Соглашения о вызовах для разных архитектур.
Видео-ответ на комментарии к ролику с решением задачи, решение которой так никто и не предложил (без использования ассемблера, в т.ч., ассемблерной вставки в программу на C, задачу не решить): [ Ссылка ]
Специфичные задачи, которые можно решить с использованием ассемблера. Соглашения о вызовах для архитектур: x86, x64, arm, mcs-51
В видео решается задача:
Как вызвать из языка более высокого уровня подпрограмму из встроенного начального загрузчика, расположенного во внутреннем ПЗУ микроконтроллера, с передачей аргумента, не прибегая к языку низкого уровня (ассемблеру)? Причем, подпрограмма (функция) в этом встроенном загрузчике не соответствует соглашению о вызовах функций (регистры, стек, возвращаемое значение и т.п., если понимаете, о чем я).
Внимание! Уточнение!
9:45 Обратите внимание, что компилятор сгенерировал инструкцию LJMP (переход по абсолютному 16-битному адресу), а не инструкцию LCALL (вызов подпрограммы по абсолютному 16-битному адресу). Почему он так сделал? А потому что программа состояла всего из двух инструкций, оканчивающихся именно вызовом подпрограммы. Если бы после вызова нашей подпрограммы следовали бы еще инструкции, то компилятор сгенерировал бы для вызова подпрограммы инструкцию LCALL. При этом, генерируя инструкцию LJMP, компилятор подразумевает, что выход из основной программы будет осуществлен по завершению подпрограммы по инструкции RET (возврат из подпрограммы). На 12:43 я немного накосячил, "под впечатлением от этой инструкции", сгенерированной компилятором, поэтому в своей вставке на ассемблере также автоматически указал инструкцию LJMP. Однако, если речь идет именно о вызове подпрограммы по адресу, а не переходе по адресу, то, как вы понимаете, инструкция должна быть LCALL.
Еще один важный и имеющий непосредственное отношение к теме момент. Вызов внешних подпрограмм "по классике" для языка С-51 предлагается делать по такой "схеме":
typedef void my_func(unsigned char);
my_func* send_byte = (my_func*)SEND_BYTE_SP0;
send_byte(65);
Т.е. объявляется тип, затем объявляется переменная-указатель данного типа с инициализацией в ней адреса подпрограммы. И в заключении осуществляется вызов подпрограммы. Прекрасно, но посмотрим, что выдаст на выходе компилятор... Остальное читайте в закрепленном комментарии, т.к. ютуб в описании делает ненужные хэштеги из констант ассемблера.
#ассемблер
#микроконтроллер
#программирование
Ещё видео!