正如标题中所说,我的目标是用C和ARM汇编编写一个程序,通过将每个字符的字节值移动一定量来解码字符串。“space”字符没有移位,只是复制到结果字符串。当找到空终止符时,进程结束。
这是我的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

问题是,它只经过一次循环,然后就卡住了。有时它会沿着“sim:unknown SWI…”或“unknown v6 isbn…”的行打印错误。或者最糟糕的是,它什么也不打印(无限循环?)
我不知道问题出在哪里,我的逻辑似乎有道理。
我读取下一个字节:
如果它是空终止符,我也将它放入结果字符串中,并结束循环。
如果是空格,我将空格放在结果字符串中,然后继续循环。
如果它>=65(它应该是,除非空格/空结束符),我减去移位值。如果结果值>=65,我将其放入结果字符串中。如果小于65,我加26,然后把它放到结果字符串中,因此成功地包装到字母表的大写字母。
不应该有别的情况。
但我仍然会有错误,或者可能是无限循环。有什么想法吗?

最佳答案

str a1, bufferAddr将寄存器中的值存储在bufferAddr指向的内存位置。因为这是在init函数的中间,所以它只在第一次工作。
但是ldr v2, =bufferAddr加载bufferAddr的值,这会导致结果覆盖decrypt
您应该使用ldr v2, bufferAddr

08-16 23:30