ARM汇编问题(没有足够的寄存器!)
ARM Assembly question (there is not enough register!)
您好,我正在尝试编写进行模式搜索的代码,并将最流行的模式排在前 3 位,以及计算模式的次数。
我可以编写对 top2 模式进行排名的代码。但是我做不到rank3.
(我是这样分配寄存器的)
R7 : top1 模式的计数
R8 : top1 模式
R10 : top2 模式的计数
R11:top2 模式
这是我的实际代码
void ex3(){
int result[4];
example3(0x00,0x100, 0x0, result);
sendstr("Top 1 pattern : ");
printDecimal(result[0]);
sendstr("\n");
sendstr("Top 1 pattern count : ");
printDecimal(result[1]);
sendstr("\n");
sendstr("Top 2 pattern : ");
printDecimal(result[2]);
sendstr("\n");
sendstr("Top 2 pattern count : ");
printDecimal(result[3]);
sendstr("\n");
}
PRESERVE8
AREA Ex3, CODE, READONLY
EXPORT example3
example3
STMFD sp!,{r4-r9,lr}
MOV R4, r2
MOV R6, R3
MOV R7, #0
MOV R8, #0
Loop2
MOV r3, #0
MOV r9, r0
Loop
LDRB r5, [r9], #1
CMP r4, r5
ADDEQ r3, r3, #1
CMP r9, r1
BLS Loop
CMP R3, R7
BLT Com2
Com1
MOVGT R10,R7
MOVGT R11,R8
MOVGT R7, R3
MOVGT R8, R4
B Here
Com2
CMP R3,R10
BLT Here
MOVGT R10,R3
MOVGT R11,R4
CMP R4, #0XFF
ADDLT R4, R4, #1
BLT Loop2
STR r8, [r6]
STR r7, [r6,#4]
STR r11, [r6,#8]
STR r10, [r6,#12]
LDMFD sp!,{r4-r9,lr}
MOV PC, lr
END
但是当我尝试使用相同逻辑的 rank3 代码时,只是以这种方式更改了寄存器分配
r7 count of top1 pattern
r8 top1 pattern
r9 top2 count
r10 TOP2
r11 top3 count
r12 top3
它显示奇怪的结果,因为(在我看来)错误的寄存器分配(我需要更多空寄存器...)。解决寄存器不足的简单方法或正确方法是什么?
PRESERVE8
AREA Ex3, CODE, READONLY
EXPORT example3
example3
STMFD sp!,{r4-r9,lr}
MOV R4, r2
MOV R6, R3
MOV R7, #0
MOV R8, #0
Loop2
MOV r3, #0
MOV r9, r0
Loop
LDRB r5, [r9], #1
CMP r4, r5
ADDEQ r3, r3, #1
CMP r9, r1
BLS Loop
CMP R3, R7
BLT Com2
Com1
MOVGT R11,R9
MOVGT R12,R10
MOVGT R9,R7
MOVGT R10,R8
MOVGT R7, R3
MOVGT R8, R4
B Here
Com2
CMP R3,R9
BLT Com3
MOVGT R11,R9
MOVGT R12,R10
MOVGT R9,R3
MOVGT R10,R4
B Here
Com3
CMP R3,R11
MOVGT R11,R3
MOVGT R12,R4
Here
CMP R4, #0XFF
ADDLT R4, R4, #1
BLT Loop2
STR r8, [r6]
STR r7, [r6,#4]
STR r10, [r6,#8]
STR r9, [r6,#12]
STR r12, [r6,#16]
STR r11, [r6,#20]
LDMFD sp!,{r4-r9,lr}
MOV PC, lr
END
编译器会怎么做?尝试编写一些 C 来做同样的事情,并让编译器生成汇编语言(如果您使用的是 GCC,它是 gcc -S
)。这是学习有效汇编语言的好方法;并非编译器所做的每件事都是最高效的,但它始终有效且合乎逻辑,如果禁用优化,应该相当容易遵循。
如果你 运行 完全用完寄存器,你唯一的选择是使用堆栈作为本地存储,并根据需要压入和弹出寄存器,或者分配一点堆栈 space 和 LDR
/STR
根据需要从该区域取值。但是,在您的情况下,您没有从函数内调用任何其他函数,因此没有理由避免 r0-r3
或 r12
,它们被调用破坏了。
请注意,您提供的代码至少包含一个错误,因为您正在使用 r10-r11
并且没有通过 STMFD
和 LDMFD
指令保留它们的内容。
您好,我正在尝试编写进行模式搜索的代码,并将最流行的模式排在前 3 位,以及计算模式的次数。 我可以编写对 top2 模式进行排名的代码。但是我做不到rank3.
(我是这样分配寄存器的)
R7 : top1 模式的计数
R8 : top1 模式
R10 : top2 模式的计数
R11:top2 模式
这是我的实际代码
void ex3(){
int result[4];
example3(0x00,0x100, 0x0, result);
sendstr("Top 1 pattern : ");
printDecimal(result[0]);
sendstr("\n");
sendstr("Top 1 pattern count : ");
printDecimal(result[1]);
sendstr("\n");
sendstr("Top 2 pattern : ");
printDecimal(result[2]);
sendstr("\n");
sendstr("Top 2 pattern count : ");
printDecimal(result[3]);
sendstr("\n");
}
PRESERVE8
AREA Ex3, CODE, READONLY
EXPORT example3
example3
STMFD sp!,{r4-r9,lr}
MOV R4, r2
MOV R6, R3
MOV R7, #0
MOV R8, #0
Loop2
MOV r3, #0
MOV r9, r0
Loop
LDRB r5, [r9], #1
CMP r4, r5
ADDEQ r3, r3, #1
CMP r9, r1
BLS Loop
CMP R3, R7
BLT Com2
Com1
MOVGT R10,R7
MOVGT R11,R8
MOVGT R7, R3
MOVGT R8, R4
B Here
Com2
CMP R3,R10
BLT Here
MOVGT R10,R3
MOVGT R11,R4
CMP R4, #0XFF
ADDLT R4, R4, #1
BLT Loop2
STR r8, [r6]
STR r7, [r6,#4]
STR r11, [r6,#8]
STR r10, [r6,#12]
LDMFD sp!,{r4-r9,lr}
MOV PC, lr
END
但是当我尝试使用相同逻辑的 rank3 代码时,只是以这种方式更改了寄存器分配
r7 count of top1 pattern
r8 top1 pattern
r9 top2 count
r10 TOP2
r11 top3 count
r12 top3
它显示奇怪的结果,因为(在我看来)错误的寄存器分配(我需要更多空寄存器...)。解决寄存器不足的简单方法或正确方法是什么?
PRESERVE8
AREA Ex3, CODE, READONLY
EXPORT example3
example3
STMFD sp!,{r4-r9,lr}
MOV R4, r2
MOV R6, R3
MOV R7, #0
MOV R8, #0
Loop2
MOV r3, #0
MOV r9, r0
Loop
LDRB r5, [r9], #1
CMP r4, r5
ADDEQ r3, r3, #1
CMP r9, r1
BLS Loop
CMP R3, R7
BLT Com2
Com1
MOVGT R11,R9
MOVGT R12,R10
MOVGT R9,R7
MOVGT R10,R8
MOVGT R7, R3
MOVGT R8, R4
B Here
Com2
CMP R3,R9
BLT Com3
MOVGT R11,R9
MOVGT R12,R10
MOVGT R9,R3
MOVGT R10,R4
B Here
Com3
CMP R3,R11
MOVGT R11,R3
MOVGT R12,R4
Here
CMP R4, #0XFF
ADDLT R4, R4, #1
BLT Loop2
STR r8, [r6]
STR r7, [r6,#4]
STR r10, [r6,#8]
STR r9, [r6,#12]
STR r12, [r6,#16]
STR r11, [r6,#20]
LDMFD sp!,{r4-r9,lr}
MOV PC, lr
END
编译器会怎么做?尝试编写一些 C 来做同样的事情,并让编译器生成汇编语言(如果您使用的是 GCC,它是 gcc -S
)。这是学习有效汇编语言的好方法;并非编译器所做的每件事都是最高效的,但它始终有效且合乎逻辑,如果禁用优化,应该相当容易遵循。
如果你 运行 完全用完寄存器,你唯一的选择是使用堆栈作为本地存储,并根据需要压入和弹出寄存器,或者分配一点堆栈 space 和 LDR
/STR
根据需要从该区域取值。但是,在您的情况下,您没有从函数内调用任何其他函数,因此没有理由避免 r0-r3
或 r12
,它们被调用破坏了。
请注意,您提供的代码至少包含一个错误,因为您正在使用 r10-r11
并且没有通过 STMFD
和 LDMFD
指令保留它们的内容。