assembly 是否有办法将此C代码转换为ARM内联汇编?

6tr1vspr  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(138)

这是一个凯撒密码的C代码,它以给定的文本和加密密钥作为参数。我必须将其转换为ARM内联汇编程序。

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;
    }
  }
}

在这里,我使用了65、90、97、122和0,因为它们是ASCII值“A”、“Z”、“a”、“z”和“\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"
  );
}

上面的代码是我目前为止所做的,但似乎不起作用。我做错了什么?

ijnw1ujt

ijnw1ujt1#

好吧,你 * 可以 * 使用合适的gcc交叉编译器来生成汇编代码。但是我不确定这是否满足你的要求。
将代码保存到rot.c中并运行以下代码,将gcc替换为适用于您的ARM设备的交叉编译器版本:

gcc rot.c -S -O0

上面的命令还关闭了优化(-O0),这可能会有所帮助。
将生成一个rot.s,其中包含该文件的整个程序集。您不需要整个文件,但它可以帮助您找出手动移植工作中的错误。

jaxagkaj

jaxagkaj2#

.syntax unified
.arch armv5
.global rotN
.text

// void rotN(char *str, int n);

pStr        .req    r0
delta       .req    r1
currChar    .req    r2
temp        .req    r3
dummy       .req    r12

.balign 64
.func
rotN:
    ldrb    currChar, [pStr], #1

.balign 16
1:
    cmp     currChar, #0
    add     temp, currChar, delta
    bxeq    lr

    cmp     currChar, #97
    rsbshs  dummy, currChar, #122
    blo     5f

    cmp     temp, #122
    subhi   temp, temp, #26
    ldrb    currChar, [pStr], #1
    strb    temp, [pStr, #-2]
    b       1b

.balign 16
5:
    cmp     currChar, #65
    rsbshs  dummy, currChar, #90
    ldrb    currChar, [pStr], #1
    blo     1b

    cmp     temp, #90
    subhi   temp, temp, #26
    strb    temp, [pStr, #-2]
    b       1b

.endfunc
.end

以上是使用标准指令集的纯汇编版本。
把它当作教科书上的例子,最多比C版本快10%左右。(值得吗??)
请不要问更多的细节问题。只要按照它的指示,直到你完全理解整个代码-这是最好的学习方式。
如果是一项专业任务,并且CPU是armv6或更高,我会使用增强的DSP/SIMD指令,使其速度提高一倍左右,但这是一个不同的故事。

相关问题