This is a C code of Caesar Cipher which takes a given text and an encryption key as its parameters. I have to convert this into ARM Inline Assembler.
void rotN(char *str, int n)
{
char *p;
for (p = str; *p != 0; p++)
{
int currChar = (int)*p;
if (currChar >= 97 && currChar <= 122)
{
currChar = currChar + n;
if (currChar > 122)
{
currChar = currChar - 26;
}
*p = (char)currChar;
}
if (currChar >= 65 && currChar <= 90)
{
currChar = currChar + n;
if (currChar > 90)
{
currChar = currChar - 26;
}
*p = (char)currChar;
}
}
}
Over here I've used 65, 90, 97, 122 and 0 as they're ASCII values of 'A', 'Z', 'a', 'z' and '\0'.
void rotN(char *str, int n){
asm volatile(
"str %[str], [%[str]]\n\t"
"mov r0, %[n]\n\t"
"mov r1, %[str]\n\t"
"mov r2, #0\n\t"
"1: ldrb r3, [r1, r2]\n\t"
"cmp r3, #0\n\t"
"beq 2f\n\t"
"cmp r3, #97\n\t"
"blo 2f\n\t"
"cmp r3, #122\n\t"
"bhi 2f\n\t"
"sub r3, r3, #26\n\t"
"b 1b\n\t"
"2: add r3, r3, r0\n\t"
"cmp r3, #122\n\t"
"bhi 2f\n\t"
"cmp r3, #97\n\t"
"blo 2f\n\t"
"sub r3, r3, #26\n\t"
"b 1b\n\t"
"2:\n\t"
"strb r3, [r1, r2]\n\t"
:
: [str] "r" (str), [n] "r" (n)
: "r0", "r1", "r2", "r3"
);
}
The code above is what I've done so far, but doesn't seem to work. What am i doing wrong?
Above is a pure assembly version utilizing the standard instruction set.
Consider it a textbook example which is roughly 10% faster at best than the C version. (Is it worth it???)
Please do not ask further questions about details. Just follow it instruction by instruction until you fully understand the whole code - This is the best way to learn.
If it were a professional assignment, and the CPU is
armv6
or higher, I'd use enhanced DSP/SIMD instructions and make it around twice as fast, but that's a different story.