ARM程序集中的凯撒解码器

时间:2016-04-15 17:41:49

标签: c string gcc assembly arm

正如标题中所说,我的目标是在C和ARM程序集中编写一个程序,通过将每个字符的字节值移动一定量来解码字符串。 "空间"字符不会移位,而只是复制到结果字符串。当找到空终止符时,该过程结束。

这是我的C代码:

#include <stdio.h>

extern void init(char * encrypt);
extern char * decrypt(char * encrypt, int shift);

int main(int argc, char * argv[])
{
    char * result;
    char encrypt[] = "GSRKVEXYPEXMSRW CSY LEZI JSYRH XLI WLMJX ZEPYI";
    int i;

    init(encrypt);
    for (i = 1; i < 5; i++) {
        result = decrypt(encrypt, i);
        printf("Possible decrypt with shift %d: %s\n", i, result);
    }
}

这是我的ARM代码(这是一个名为decrypt.s的文件)​​:

@ init: reserves space for the decryption
    .global init
    .text
init: stmfd sp!, {v1-v6, lr}
    mov v1, a1
    bl strlen
    bl malloc
    bufferAddr: .fill 4, 1, 0
    str a1, bufferAddr
    @mov a2, v1
    @bl strcpy

    ldmfd sp!, {v1-v6, pc}

@ decrypt: performs shifting of letters to decrypt string
    .global decrypt
    .text
decrypt: stmfd sp!, {v1-v6, lr}
    mov v1, a1 @ v1 is the pointer to encrypt (string)
    ldr v2, =bufferAddr @ v2 is the pointer to result (string)

    loop:
        ldrb v3, [v1], #1 @ v3 is the current char (8-bit number)

        cmp v3, #0
        streqb v3, [v2], #1
        beq endLabel

        cmp v3, #32 @ check if v3 == "space"
        streqb v3, [v2], #1 @ if true, store space in result, increment
        beq loop @ if true, proceed to next char

        sub v3, v3, a2 @ shift v3 by shift-value
        cmp v3, #65 @ check if v3 >= 65 (A)
        strgeb v3, [v2], #1 @ if true, store char in result, increment
        bge loop

        @ if less than A
        add v3, v3, #26 @ add 26, wrap between A-Z
        strb v3, [v2], #1 @ if true, store char in result, increment
        b loop
    endLabel:

    ldr a1, =bufferAddr

    ldmfd sp!, {v1-v6, pc}
.end

问题是,它只会经历一次循环,然后就会卡住。有时它会按照&#34; sim:未知的SWI ...&#34;或者&#34;未知的v6 isbn ...&#34;。或者最糟糕的是,它什么都不打印(无限循环?)

我不确定问题是什么,我的逻辑似乎有道理。 我读了下一个字节:

  • 如果它是null-terminator,我也把它放在结果字符串中,然后结束循环。
  • 如果是空格,我将空格放在结果字符串中,然后继续循环。
  • 如果它&gt; => 65(它应该是,除非Space / null-terminator),我减去shift值。如果结果值>> = 65,我将其放在结果字符串中。如果&lt;&lt; s&lt; 65,我加26,然后把它放在结果字符串中,因此成功地换成字母表的大写字母。
  • (应该)没有其他案例。

然而,我仍然会遇到错误,或者可能是无限循环。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

str a1, bufferAddr将寄存器中的值存储在bufferAddr指向的内存位置。由于它位于init函数的中间,因此它仅适用于第一次。

但是ldr v2, =bufferAddr会加载bufferAddr的值,这会导致结果覆盖decrypt

您应该使用ldr v2, bufferAddr