【问题标题】:Questions about IT conditional codes in assembly关于汇编中IT条件码的问题
【发布时间】:2018-10-06 16:32:55
【问题描述】:

大多数示例都有如下 IT 命令,

ITTE   NE        ; IT can be omitted
ANDNE  r0,r0,r1  ; 16-bit AND, not ANDS
ADDSNE r2,r2,#1  ; 32-bit ADDS (16-bit ADDS does not set flags in IT block)
MOVEQ  r2,r3     ; 16-bit MOV

ITT    AL        ; emit 2 non-flag setting 16-bit instructions
ADDAL  r0,r0,r1  ; 16-bit ADD, not ADDS
SUBAL  r2,r2,#1  ; 16-bit SUB, not SUB
ADD    r0,r0,r1  ; expands into 32-bit ADD, and is not in IT block

ITT    EQ        
MOVEQ  r0,r1
BEQ    dloop     ; branch at end of IT block is permitted

ITT    EQ
MOVEQ  r0,r1
BKPT   #1        ; BKPT always executes
ADDEQ  r0,r0,#1   

我想看看示例中的最后一个 IT 块。 我真的很困惑发生了什么。对于 MOVEQ,我认为它是检查 r0 = r1,如果它们相等则将 r1 移动到 r0。但如果他们是平等的,那就没有意义了。到底发生了什么?

我写了一个拇指代码来检查哪个数字更大:

cmp r0, r1
ITE HS
movhs r0, r0
movlo r0, r1

这里我需要在 IT 块之前比较寄存器... 但是为什么所有的例子都至少事先不包括比较呢?是否有另一种方法可以为我的示例编写不包含比较的 IT 块?这些示例中到底发生了什么?

【问题讨论】:

  • 不幸的是,大多数解释都是为熟悉ARM汇编程序的程序编写的,试图使用THUMB2和IT。在这种情况下,您之前已经设置了条件代码,这类似于几乎所有汇编器/机器体系结构中存在的“条件分支”指令。所以文档/示例通常假设您知道这一点,并且只显示需要添加到 ARM 代码(IT 语句)的条件,然后解释IT 编码(ITEITT 等) .

标签: assembly arm stm32 thumb


【解决方案1】:

标志是 IT 块内的谓词指令的输入。是的,您确实在it 之前的某个时间点放置了cmpadds 或任何其他标志设置指令。之前不必正确

您展示的示例用于记录 IT 的极端案例,而不是使用它来实际执行特定操作的完整/完整示例。

条件分支指令的文档通常也不显示标志设置指令。


根据ARM's docs

除了 CMP、CMN 和 TST,通常影响条件代码标志的 16 位指令在 IT 块内使用时不会影响它们。

但其中一个示例确实清楚地表明您可以在 IT 块内使用 32 位 adds 更改标志,这告诉我们允许常规比较/测试指令。

文档没有明确说明对 IT 块标志的更改会影响块内以后的谓词指令。 @DanLewis 的回答证实了他们这样做。

在 ARM 模式下,不需要 IT 块来执行谓词(每条指令中的 4 位编码一个谓词),因此标志设置指令显然会影响后面的指令。它在 Thumb 模式下的工作方式相同是有道理的,特别是因为 IT 在某些语法中是可选的。 (如果汇编为拇指模式,一些汇编程序会以统一的语法为您插入。)

【讨论】:

  • 这更有意义。我最初认为(被称为 IF Then 和所有)它正在块内进行比较。因此,对于 IT 块,您事先设置标志,然后 IT 块调整这些标志并相应地执行操作码。标志可以在 IT 块内更改吗?谢谢!
  • @Darklink9110:是的,您可以更改 IT 块内的标志,文档对此很清楚。他们不清楚这是否对当前块的 rest 有任何影响。
【解决方案2】:

@Darklink9110:是的,您可以更改 IT 块内的标志,文档对此很清楚。 > 他们不清楚这是否对当前区块的其余部分有任何影响。

我在 ARM Cortex-M4 (Thumb-2) 上测试了以下两个函数以找出答案,结果表明,如果 IT 块内的指令更改标志,则同一 IT 块中的后续指令 (1 ) 例如 ADC、SBC 和 RRX 确实使用了新的标志值,并且 (2) 可能会根据新的标志值改变其启用/禁用状态。

// 在 IT 块中,执行使用进位标志(例如 ADC)的指令,参见 // 同一 IT 块中的先前指令导致进位标志的变化? 测试1:MOV R0,1 // R0 = 1 CMP R0,R0 // C = 0, Z = 1 (EQ) ITT 均衡器 LSRSEQ R0,R0,1 // C = 1, Z = 1 (EQ), R0 = 0 ADCEQ R0,R0,0 // R0 = R0 + C BX LR // **在 R0 中返回 1** // 执行 IT 块更新中由指令更改的标志 // 同一 IT 块中的后续指令启用/禁用? Test2: MOV R0,1 // R0 = 1 CMP R0,R0 // Z = 1 (EQ) ITT 均衡器 CMPEQ R0,0 // Z = 0 (NE) MOVEQ R0,0 // R0 = 0 ? (已禁用!) BX LR // **在 R0 中返回 1**

【讨论】:

    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    相关资源
    最近更新 更多