【问题标题】:ARMv7-M assembly ITEE usageARMv7-M 程序集 ITEE 使用
【发布时间】:2016-08-31 17:01:36
【问题描述】:
  • 问题:

我试图让 ITEE EQ 即“If-Then-Else-Else Equal”块在 R6==0 时工作,THEN 分支到END 标签,但汇编程序在该行中调用 error:BEQ END

  • 节目信息:

我正在做一个与优化相关的程序。我正在使用梯度下降收敛到梯度为 0 的点,以找到使某些函数 f(x) 最小化的解 x*。我用C语言调用了一个汇编函数,这里就是这个程序。

这是我的程序,错误是:

        CMP R6, #0          @ Compare f'(x) with 0
        ITEE EQ             @ If R6 == 0, Then-Else-Else
        BEQ END             @ Calls END label if equal
        SUBNE R0, R6        @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal
        BNE optimize        @ Branch to optimize if not equal

这是我第一个使用 NXP LPC1769 完成学校作业的装配程序。请让我知道我错过了什么或我做错了什么。谢谢!

这是我的整个程序:

.syntax unified
.cpu cortex-m3
.thumb
.align 2
.global optimize
.thumb_func

optimize:
@  Write optimization function in assembly language here

        MOV R5, INLAMBDA    @ R5 holds value of inverse lambda(10) ie to eliminate floating point
        LDR R6, #2          @ Load R6 with value '2' ie constant of f'(x)
        MUL R6, R1, R6      @ Multiply R6(2) with R1(a) & store to R6(results)
        MLA R6, R6, R0, R2  @ Multiply R6(results) with R0(x) & sum with R2(b) to get f'(x). Store & update results to R6
        SDIV R6, R5         @ Divide R6(results) by R5(1/lambda) to get f'(x) * lambda

        CMP R6, #0          @ Compare f'(x) with 0
        ITEE EQ             @ If R6 == 0, Then-Else-Else
        BEQ END             @ Calls END label if equal
        SUBNE R0, R6        @ Change R0(x) in the opp direction of gradient to get lower value of f(x) if not equal
        BNE optimize        @ Branch to optimize if not equal

@  End label
END:

BX LR

@ Define constant values
CONST: .word 123
INLAMBDA: .word 10      @ Inverse lambda 1 / lambda(0.1) is 10

【问题讨论】:

  • 错误信息告诉你究竟是什么问题:Error: branch must be last instruction in IT block -- 'beq END'
  • 除非是,比如说,armasm 的“错误:A1603E:IT 块中的这条指令具有不可预测的结果”,这不太清楚,或者可能是其他一些更无帮助的汇编程序。无论哪种方式,在问题本身中包含特定错误消息总是好的,尤其是因为许多人对不熟悉的错误所做的第一件事是将其粘贴到搜索引擎中以查看出现了什么。

标签: if-statement assembly arm branch lpc


【解决方案1】:

问题在于BEQ END 位于 IT 块的中间。引用some documentation for IT:

仅当 IT 块中的最后一条指令时,才允许在 IT 块中使用分支或任何修改 PC 的指令。

也就是说,因为它是一个分支,“else”无论如何都是隐含的——如果你选择这个分支,你将不会因为在别处而执行以下指令,如果你不要认为你别无选择,只能执行它们,所以它们根本不需要明确的条件。事实上,您甚至不需要IT,因为B<cond> 本身就有适当的Thumb 指令编码。但是你甚至不需要那个,因为你正在做一个基于寄存器为零的短前向分支,并且有一个特定的 Thumb-only compare-and-branch 指令可以准确地完成那个!

换句话说,你最初的 5 行 sn-p 可以简单地表示为:

CBZ R6, END
SUB R0, R6
B optimize 

【讨论】:

  • 我以前从未见过CBZ。这是一个漂亮的小指令。
猜你喜欢
  • 2015-02-13
  • 1970-01-01
  • 2018-06-20
  • 2020-06-22
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
相关资源
最近更新 更多