#c #assembly #arm #armv7
#c #сборка #arm #armv7
Вопрос:
Я новичок в программировании на языке ассемблера ARM7.
Я пытаюсь реализовать простую функцию в ARM assembly, которая принимает массив символов, переворачивает его и сохраняет в другой массив символов равной длины.
Ниже я включил как свой код на C, так и код на языке ассемблера ARM7. Однако мой код не выводит правильную перевернутую строку; что, вероятно, связано с моими инструкциями ASM. Я использую Linux на 32-разрядной машине.
reverseString.s (код ниже)
.global reverseString
.text
reverseString:
MOV R2, R1 @store strIn[0] into R2
PUSH {R4-R6} @save regs
MOV R4, #0 @R4 will be strIn_len reg, store 0 for count
@finds the length of the strIn arr
strlen_loop:
LDR R3, [R2], #1 @increment through strIn arr
ADD R4, R4, #1 @count the no. of chars
CMP R3, #0 @check if null term hit
BNE strlen_loop @if yes leave, else cont.
@string reversal loop
MOV R0, R2 @movs ptr of strOut to last element
loop:
CMP R4, #0 @makes sure count !=0
BEQ loop_end @if yes, end loop
LDR R5, [R1], #1 @incr. address of strIn in R1 and put into R5
STR R5, [R0], #-1 @store the value at address in strOut
SUB R4, R4, #1 @decrement counter var
B loop
loop_end:
POP {R4-R6} @restore regs
BX LR
reverseString.c (код ниже)
#include <stdio.h>
#include <stdint.h>
extern void reverseString(char strOut[], const char strIn[]);
#define COUNT 6
int main()
{
const char strIn[COUNT] = "candy";
char strOut[COUNT];
reverseString(strOut, strIn);
printf("%srn", strOut);
return 0;
}
скомпилирован в командной строке с использованием
gcc -g -o reverseString reverseString.s reverseString.c
./reverseString
Комментарии:
1. Какой результат вы получаете? Вы прошли через это в отладчике? Почему
strIn
значение const, когда вы собираетесь его изменить?2. Спасибо за вашу помощь. Я использовал отладчик и пошагово проверил весь код. После проверки регистров они уменьшаются и инкрементируются должным образом. Кажется, что в регистре может быть мусор, как только я получу к нему доступ. Поскольку мой вывод выглядит как приведенный выше мусор. Также
strIn
предполагается, что он не изменился. Я просто хочу получить доступ к элементам (не изменять их значения).3. Вы можете передать указатель src как const , но вы не можете объявить исходный массив как const, если собираетесь изменять его с помощью scanf. Возможно, вам будет полезно поиграть с некоторым кодом C, скомпилированным для ARM. Это может помочь разработать логику на потенциально более знакомом языке. godbolt.org/z/e1uq_Q Поскольку вы копируете по 1 байту за раз, вам может потребоваться использовать эти конкретные инструкции.
4. Да, вы правы. Это была оплошность с моей стороны, и ее не следует объявлять как const, если я собираюсь использовать scanf. Я исправлю это и сделаю его постоянным. Также, спасибо за ссылку на этот веб-сайт, это очень полезно.
5. Вы пытаетесь использовать ARM7 или ARMv7?
Ответ №1:
Попробуйте провести эксперимент. Инициализируйте strOut
что-нибудь, а после вызова reverseString
выведите оба strIn
и strOut
. Обратите внимание на несколько забавный результат.
Теперь, в
MOV R0, R2 @movs ptr of strOut to last element
Последний элемент чего именно?
R2
в strlen_loop
приведенном выше примере пройден strIn
, и в этой точке содержится адрес его конца. Теперь R0
также содержит этот адрес, а остальной код не имеет к strOut
никакого отношения. Он пытается выполнить обратное strIn
.
Этот шаг не только вреден, но и избыточен. Просто скопируйте из [R2], #-1
в [R0], #1
.
Комментарии:
1. Спасибо, что уделили мне время. Когда вы говорите копировать из
[R2], #-1
вR0], #1
, какая это строка? ЭтоSTR R5, [R0], #-1
?