Сборка ARM, сравнивающая два символа (ascii) - PullRequest
0 голосов
/ 25 октября 2018
test:
    ldr r0, [r1, #4]
    bl printf

    ldr r2, [r1, #4]
    ldrb r0, [r2], #1

    cmp r0, #32
    beq test
# 32 - десятичный ASCII-код пространства

код компилируется с использованием

arm-none-eabi-gcc a.s -T generic-hosted.ld

, затем выполняется с

arm-none-eabi-run a.out "abcde"
arm-none-eabi-run a.out " bcde"

Я предполагаю, что первая команда выведетодин раз вывести «abcde», второй с пробелом должен вывести «bcde» дважды.Но я получаю обе печати один раз, в чем проблема?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Ответ Тимоти Болдуина точен, но я подумал, что немного расширю его.Двоичный интерфейс приложения ARM (ABI) и, в частности, стандарт вызова процедуры , определяет, как обрабатывается каждый регистр через границы вызова процедуры.

В итоге, r0-r3 используется в качестве аргументаи передача возвращаемого значения, и она должна быть сохранена вызывающим вместе с «регистром обработки внутренних вызовов» r12.Все остальные регистры общего назначения должны сохраняться вызываемой .Поэтому, если вы пишете свои собственные функции на языке ассемблера, вы должны нажать любой из r4-r11, который вы используете, в дополнение к lr (r14), если вы вызываете любые другие функции, и вы должны убедиться, что вы используетестек «сбалансирован», так что sp (r13) имеет то же значение на выходе, что и на входе.

Большинство компиляторов (по крайней мере, с отключенными оптимизациями) генерируют код, отвечающий этим требованиям, перемещаялюбые аргументы функции из r0-r3 в самом начале, сразу после нажатия регистров сохранения вызываемого объекта;путем перемещения любого возвращаемого значения в r0 непосредственно перед возвратом;и используя r0-r3 только для передачи аргументов вызываемым функциям и из них во время выполнения функции.

Кроме того, для всех функций в разных объектных файлах (т.е. в разных исходных файлах) стек должен быть выровнен по 8 байтов,и это хорошая привычка всегда поддерживать 8-байтовое выравнивание, потому что это легко сделать и это бесплатно (по причинам, связанным с кешем).Для этого убедитесь, что каждое взаимодействие со стеком (каждые PUSH и POP) включает в себя четное количество регистров, добавляя и выдвигая дополнительные регистры, если необходимо составить четное число.

0 голосов
/ 25 октября 2018

printf может изменять r0, r1, r2, r3 и r12.

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

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