Ну, не весь ваш код присутствует в вопросе, но главное, что выделяется, это то, что вы не сохраняете правильные регистры внутри и между вашими функциями.
Приложение ARMДвоичный интерфейс обозначает r0-r3
для передачи параметров и возвращаемых значений, поэтому сохранение значений r0-r3
в вашей функции является неправильным.Действительно, ABI утверждает, что
Подпрограмма должна сохранять содержимое регистров r4-r8
, r10
, r11
и SP
(и r9
в вариантах PCS, которые обозначают r9
as v6
)
и если вы не уверены, какой статус r9
находится на вашей платформе, играйте безопасно и сохраните его тоже.
Так что вам нужносохранить что-нибудь важное в r0-r3
и r12
перед вызовом функции и сохранить r4-r11
внутри нее.Вам также необходимо убедиться, что использование стека функции сбалансировано, следовательно, сохраняется sp
(r13
).
Вы также должны сохранить регистр связи (lr
, r14
), если ваша функциявызывает любые другие функции, в противном случае вы теряете свой обратный адрес (этот шаг также отсутствует в drawline
как написано).
Конечно, если единственные функции, которые вы когда-либо вызывали, являются вашими собственными, а ваши функции вызываются толькосвоим собственным кодом вы можете нарушить ABI - но я не знаю, почему вы этого хотите, и сохранение lr
все равно потребуется.
К вашему сведению порядок регистров в вашем *Инструкции 1038 * и pop
(на самом деле STMDB
и LDMIA
) не имеют значения;инструкции кодируются битовыми полями, описывающими регистры, которые должны быть сохранены или загружены, и порядок, в котором они хранятся и извлекаются, соответствует возрастающим номерам регистров, занимающим восходящие ячейки памяти.Большинство сборщиков ARM предупредит вас, если вы попытаетесь указать список регистров в любом другом порядке, кроме как в порядке возрастания, поскольку они предполагают, что вы пытаетесь получить какую-то конкретную загрузку или порядок хранения, который вы не получите.
Наконецобратите внимание, что вы должны использовать привычку вставлять и выталкивать четные числа регистров, чтобы поддерживать 8-байтовое выравнивание стека - возможно, вы уже знаете это, потому что вы делаете это в представленном вами коде.Это помогает вашему коду быть совместимым с существующим кодом, который требует выравнивания стека в 8 байтов, которых много.