手臂汇编语言中的递归函数

时间:2018-11-03 10:22:40

标签: assembly arm

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().authorizeRequests()
            .anyRequest().hasAnyRole("USER", "ADMIN");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("{noop}user").roles("USER")
                .and()
                .withUser("admin").password("{noop}admin").roles("ADMIN");
    }

}

我已经用手臂汇编语言编写了一个代码来查找整数的阶乘。 但是此代码不会显示任何答案。我找不到原因。

1 个答案:

答案 0 :(得分:1)

来自Peter CordesElliot Alderson的有关需要提供MCV示例和需要对您的代码进行注释的评论是绝对正确的。请回复这样的请求,因为它们可以更轻松地为您提供帮助。

您最明显的错误是在L1标签之后的第五行:您重新加载lr的偏移地址不正确(您两次弹出r0的推送值)。

您应该真正解决一些奇怪的代码功能。这些中的第一个可以避免上述错误:

  • 使用STMFDLDMFD推动和弹出。与使用堆栈指针的手动操作相比,它更快且更不容易出错。如果sp包含堆栈指针(通常),则可以使用同义词PUSHPOP。例如,错误所在的三行本来可以写成

    LDMFD sp!, {r0,lr}
    

    POP {r0,lr}
    

    还请注意,您可以通过将lr的存储值直接弹出到pc而不是将其弹出到lr并发出bx lr来返回(这称为“隐式返回”并保存一行代码。

  • ARM Application Binary Interface规定函数负责保留r4-r11lrsp的内容。当然,如果您对堆栈的使用达到平衡,则会保留sp。您没有这样做。同样,由于不能保证r0-r3r12会在调用之间保留,因此通常最好避免将它们用于本地暂存存储。
  • ABI还指定在不同转换单元中的函数调用之间堆栈应为8字节对齐,因此最好始终通过推入和弹出偶数个寄存器来始终保持8字节对齐。对此没有性能损失。
  • 从风格上讲,最好将factmain分开,而不是像这样做那样将一个嵌套在另一个内部。 (您将不得不使用高级语言(包括C语言)进行这种分隔。)
  • 当您始终忽略否定参数时,为参数使用带符号类型是一个奇怪的想法。 bge使用“符号大于或等于”的比较; bhs是无符号等效项。您实际上可以使用bhi(“无符号高位”),因为如果参数为1,则在计算其阶乘时毫无意义。

我已按照以下准则重写了您的代码。我还没有添加评论,这是您要做的。我也没有修改您算法的逻辑,因此可能还有改进的空间。我也没有测试过!

    .text
    .global main
main:
    stmfd sp!, {r7,lr}

    @ compiling a recursive C procedure
    @ unsigned int fact(unsigned int n){
    @   if(n < 1){
    @       return 1;
    @   }else{
    @       return (n * fact(n-1));
    @   }
    @ }

    stmfd sp!, {r7,lr}

    @ put n in r0
    mov r0,#6

    bl fact

    mov r1,r0
    ldr r0, =format
    bl printf

    ldmfd sp!, {r7,pc}


fact:
    stmfd sp!, {r7,lr}

    cmp r0,#1
    bhi L1

    mov r0,#1
    ldmfd sp!, {r7,pc}
L1:
    mov r7,r0
    sub r0,r0,#1
    bl fact

    mov r7,r0
    mul r0,r0,r7

    ldmfd sp!, {r7,pc}


    .data
format: .asciz "The Answer is %d\n"