对于我的工作,我需要反转这部分代码(ARM9)正在做的事情。我是一个java开发者&我真的不明白这部分与单个函数相关的代码。
当然,我正在寻求帮助,因为原始代码不再可用。任何人都可以帮助我知道这个代码在任何高级语言中使用小算法做了什么?这会很好。我已经尝试了很多个小时没有结果。
sub_FFFF7B38
PUSH {LR}
ADDS R2, R0, #0
LDRB R3, [R2]
CMP R3, #0
BEQ loc_FFFF7B52
SUBS R1, #1
BCC loc_FFFF7B52
loc_FFFF7B46:
ADDS R0, #1
LDRB R3, [R0]
CMP R3, #0
BEQ loc_FFFF7B52
SUBS R1, #1
BCS loc_FFFF7B46
loc_FFFF7B52:
SUBS R0, R0, R2
POP {R1}
答案 0 :(得分:6)
除最后两行外,它可能如下所示 如果我不是100%正确,请不要打我。
如果
R0
是p0
或p
和
R1
是n
和
R2
是临时值(已编辑;首先我认为:i
或地址p0[i]
)
R3
是临时值
sub_FFFF7B38
PUSH {LR} ; save return address
ADDS R2, R0, #0 ; move R0 to R2
LDRB R3, [R2] ; load *p0
CMP R3, #0 ; if *p0==0
BEQ loc_FFFF7B52 ; then jump to loc_FFFF7B52
SUBS R1, #1 ; decrement n
BCC loc_FFFF7B52 ; if there was a borrow (i.e. n was 0): jump to loc_FFFF7B52
loc_FFFF7B46:
ADDS R0, #1 ; increment p
LDRB R3, [R0] ; load *p
CMP R3, #0 ; if *p==0
BEQ loc_FFFF7B52 ; jump to loc_FFFF7B52
SUBS R1, #1 ; decrement n
BCS loc_FFFF7B46 ; if there was no borrow (i.e. n was not 0): jump to loc_FFFF7B46
loc_FFFF7B52:
SUBS R0, R0, R2 ; calculate p - p0
POP {R1} ; ??? I don't understand the purpose of this
; isn't there missing something?
或在C:
int f(char *p0, unsigned int n)
{
char *p;
if (*p0==0 || n--==0)
return 0;
for(p=p0; *++p && n>0; n--)
{
}
return p - p0;
}
答案 1 :(得分:4)
以下是逐行评论的说明
sub_FFFF7B38
PUSH {LR} ; save LR (link register) on the stack
ADDS R2, R0, #0 ; R2 = R0 + 0 and set flags (could just have been MOV?)
LDRB R3, [R2] ; Load R3 with a single byte from the address at R2
CMP R3, #0 ; Compare R3 against 0...
BEQ loc_FFFF7B52 ; ...branch to end if equal
SUBS R1, #1 ; R1 = R1 - 1 and set flags
BCC loc_FFFF7B52 ; branch to end if carry was clear which for subtraction is
; if the result is not positive
loc_FFFF7B46:
ADDS R0, #1 ; R0 = R0 + 1 and set flags
LDRB R3, [R0] ; Load R3 with byte from address at R0
CMP R3, #0 ; Compare R3 against 0...
BEQ loc_FFFF7B52 ; ...branch to end if equal
SUBS R1, #1 ; R1 = R1 - 1 and set flags
BCS loc_FFFF7B46 ; loop if carry set which for subtraction is
; if the result is positive
loc_FFFF7B52:
SUBS R0, R0, R2 ; R0 = R0 - R2
POP {R1} ; Load what the previously saved value of LR into R1
; Presumably the missing next line is MOV PC, R1 to
; return from the function.
所以在非常基本的C代码中:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
char r3 = *r2;
if (r3 == '\0')
goto end;
if (--r1 <= 0)
goto end;
loop:
r3 = *++r0;
if (r3 == '\0')
goto end;
if (--r1 > 0)
goto loop;
end:
return r0 - r2;
}
添加一些控制结构以摆脱goto
s:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
char r3 = *r2;
if (r3 != '\0')
{
if (--r1 >= 0)
do
{
if (*++r0 == '\0')
break;
} while (--r1 >= 0);
}
return r0 - r2;
}
编辑:现在我对进位位和SUBS
的混淆已被清除,这更有意义。
简化:
void unknown(const char* r0, int r1)
{
const char* r2 = r0;
while (*r0 != '\0' && --r1 >= 0)
r0++;
return r0 - r2;
}
简而言之,这是找到NUL
字符串指针的第一个r1
字符中的第一个r0
的索引,如果没有,则返回r1
。
答案 2 :(得分:2)
Filip提供了一些指针,您还需要阅读ARM调用约定。 (也就是说,哪个寄存器包含条目上的函数参数以及它的返回值。)
从快速阅读中我认为这段代码是strnlen或与之密切相关的东西。
答案 3 :(得分:1)
这个怎么样:Instruction set for ARM
一些提示/简化asm
X:
或:Whatever:
表示以下是“子程序”。曾经在Java中使用过“goto”吗?与实际情况类似。
如果您有以下内容(忽略它是否正确arm-asm它只是pseduo):
PUSH 1
x:
POP %eax
首先它会将1放在堆栈上,然后将其弹回到eax(这是扩展ax的缩写,这是一个可以放置32位数据的寄存器)
现在,x:
做了什么?那么我们假设在此之前有100行asm,那么你可以使用“jump”指令导航到x:
。
这是对asm的一点介绍。简化。
尝试理解上面的代码并检查指令集。
答案 4 :(得分:1)
我的ASM有点生锈,所以请不要吃烂番茄。假设从sub_FFFF7B38
开始:
命令PUSH {LR}
保留链接寄存器,这是一个特殊寄存器,用于在子程序调用期间保存返回地址。
ADDS
设置标志(如CMN
会)。此外,ADDS R2, R0, #0
将R0
添加到0并存储在R2中。 (评论中Charles的更正)
LDRB R3, [R2]
正在将R2
的内容加载到主内存而不是R3
引用的寄存器中。 LDRB
仅加载一个字节。加载时,字中三个未使用的字节归零。基本上,将R2
从寄存器中取出并保存(可能)。
CMP R3, #0
在两个操作数之间执行减法并设置寄存器标志,但不存储结果。那些旗帜导致......
BEQ loc_FFFF7B521
,表示“如果之前的比较相同,请转到loc_FFFF7B521”或if(R3 == 0) {goto loc_FFFF7B521;}
因此,如果R3
不为零,则SUBS R1, #1
命令会从R1
中减去一个并设置一个标记。
BCC loc_FFFF7B52
将导致执行跳转到loc_FFFF7B52
。
(剪辑)
最后,POP {LR}
恢复在执行此代码之前在链接寄存器上保留的上一个返回地址。
编辑 - 当我在车里时,当我试图写出我的答案并且没时间用完时,Curd阐述了我的想法。