正如标题中所说,我的目标是用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
。