This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F5529:如何在汇编语言中实现递归?

Guru**** 2874030 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1005647/msp430f5529-how-to-implement-recursion-in-assembly

器件型号:MSP430F5529

您好!

我正在尝试在汇编语言中实现 C 代码、但我不知道如何实现。  C 代码如下所示:

int fib (int n) {
    if (n <= 1) {
        return n;
    }
 
    return fib(n - 1) + fib(n - 2);
}

如果返回器件类似于"return n + fib (n-1)"、则没关系。 我知道在这种情况下该怎么办。 但是、对于2个递归函数、我不知道该怎么做。

我看到了一些其他汇编架构的示例、例如 MIPS、但不了解如何 以 MSP430样式编写这些示例。

提前感谢 您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1) 1)将 return 语句重写为完全等效的序列:

    int ret;
    ret = fib(n-1);
    ret += fib(n-2);
    return(ret);

    2) 2)递归本身并不困难、只是"调用 fib"。

    3) 3)以有序的方式传递参数并保存(push/POP)局部变量将很快变得很重要。 (在编写简单的汇编程序时很容易忘记这一点。) 如果您听说过应用程序二进制接口(ABI)、这就是它的样子。 您可以自行创建或采用一个。

    4)根据(3)估算所需的堆栈大小、并确保有足够的堆栈(运行速度很快)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    实际上、我正在尝试制作一个提供 n 个 Fionacci 编号的程序。 例如、如果我给出10、程序应该给出"55"。 我编写了一个代码、但它不起作用。 我知道有问题、但我无法理解如何 解决。 可以麻烦你看一下吗?

    代码如下:

    main		mov		#10,R5          ; Program should give 10th Fibonacci number, which is "55".
    			clr		R6              ; The result will be stored in R6, so initially it is "0".
    			call	#Fibonacci
    			nop
    
    Fibonacci:
    			cmp		#2,R5           ; Checking if the number is greater than "1".
    			jge		fib             ; If yes, then jump to "fib" loop.
    			jmp		end             ; If not, then jump to "end".
    
    fib:
    			dec		R5              ; Decrease R5 in order to get "n-1"
    			mov		R5,R6           ; ret = fib(n-1)
    			dec		R5              ; Decrease R5 once more in order to get "n-2"
    			add		R5,R6           ; ret += fib(n-2)
    			call	#Fibonacci      ; Recursive function
    
    end:		ret

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    a)我希望在 Fionacci ()函数中看到对 Fionacci 的两次调用、然后是一些算术运算。 我建议你从 C 示例中将函数命名为“fib”--这不是因为汇编器很关心,但是你(和我们)可以更好地看到转换的工作方式。

    b)在第二次调用 Fionacacci 时、您从第一次调用中覆盖 R6 ("ret")、这会擦除结果。 您需要在(递归)调用上保存"ret"、这正是我在上面(3)中讨论的内容。 (我怀疑这是你的任务。)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我从阅读《小利瑟》中了解了很多关于递归的知识。 遗憾的是,没有印刷版,但后续的“小阴谋家”虽然没有那么可爱的标题,但 工作也很好。 这可能是一个比组装更好的开始位置。 这一切都与参数传递的细节有关。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当您在 C 语言中进行递归调用时、幕后会有许多事情发生。局部变量的整个状态都保存在栈中、并且*然后*执行函数。 您必须在汇编代码中复制该代码、以便有任何希望使其正常工作、这会很难看。

    递归函数仅在高级语言中很巧妙、具有大量可刻录的堆栈空间。 我从来没有明白为什么计算机科学家如此喜欢它们。 ^μ A)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Bruce。

    我忙于执行另一项任务、所以我对此没有太多的想法。 此任务的截止日期已经过、但我仍然不了解如何执行此操作、并且希望了解此操作。  更确切地说,我无法确定如何第二次调用 fib()函数。 我还使用了 C 代码到汇编转换器、但这没有帮助。 ( 转换代码的链接是: https://godbolt.org/z/zK863bxGG) 我知道它有一些冗余行、但这是我可以实现的最佳效果。

    根据转换后的代码、程序无法到达第二个调用。 因此、MSP430根本不使用12和17之间的线路。

    可以帮帮我吗?

    谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该链接似乎已失效。 您是否尝试将 MSP430编译器与"生成选项->编译器->高级->汇编器->保存.lst 文件"一起使用?

    您可能过于担心"递归"一词。 如果您假装该词从未提到过、您会如何写呼叫?  

    [编辑:固定菜单链(我认为)。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否尝试以下链接: https://godbolt.org/z/jbc66EG6b 。 它现在应该在工作。

    我尝试了 MSP430编译器、但它没有对其进行调试、因此无法获取.asm 文件。 我认为这是 因为程序 不会在寄存器中存储任何内容。

    如果我 不使用递归编写代码、代码应如下所示:

            mov     #10,R4      ; This is the "n" value
            mov     #0,R5
            mov     #1,R6
            
    fib:
            tst     R4          ; Check if the "n" is zero
            jz      exit        ; If it's zero, then end the program
            mov     R5,R10      ; Save the R5 value to R10
            add     R6,R5       ; Sum up the previous two numbers and store the result in R5
            mov     R10,R6      ; Change the R6 with R10, which stores the old R5 value
            dec     R4          ; Decrement R4
            jmp     fib         ; Jump back to "fib" loop
            
    exit:   mov     R10,R11     ; If the program is over, then show the result in R11

    它可能包含一些错误、我无法使用 CCS 和 MSP430来检查它、只是认为它应该是这样的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我很确定 fib()有一种迭代方法,但我认为这不是分配的重点。 是这样吗?