有关汇编中IT条件代码的问题

时间:2018-10-06 16:32:55

标签: assembly arm stm32 thumb

大多数示例都具有以下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块的另一种方法?这些示例中到底发生了什么?

2 个答案:

答案 0 :(得分:2)

标志是IT的输入。是的,您确实将.data input: .asciiz "Welcome to class 4" .text main: addi $v0, $0, 4 lui $v0, prompt lui $a0, $v0 syscall cmp或任何其他标志设置指令放在了adds之前的某个位置。不必先正确

您显示的示例用于记录it的极端情况,而不是使用它实际执行特定操作的完整/完整示例。

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


根据ARM's docs

  

除了CMP,CMN和TST以外,通常会影响条件代码标志的16位指令在IT块中使用时不会对其产生影响。

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

尚不清楚文档中对IT块内的标记所做的更改是否会影响该块内以后的谓词指令。我猜他们确实会这样做,但是有可能他们只是在IT封锁之后留下了改变的标志。

在ARM模式下,不需要IT块即可断言执行,因此标志设置指令始终会影响以后的指令。如果在Thumb模式下不是这种情况,那将很奇怪,尤其是因为在某些语法中adds是可选的。 (如果以拇指模式进行组装,某些汇编程序会以统一的语法为您插入它。)

答案 1 :(得分:1)

@ Darklink9110:是的,您可以更改IT块内的标志,文档很清楚。 >目前尚不清楚这是否会影响当前块的其余部分。

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

//      Inside an IT block, do instructions that use the carry flag (e.g., ADC) see
//      changes to the carry flag caused by previous instructions in the same IT block?

Test1:  MOV         R0,1        // R0 = 1
        CMP         R0,R0       // C  = 0, Z = 1 (EQ)
        ITT         EQ
        LSRSEQ      R0,R0,1     // C  = 1, Z = 1 (EQ), R0 = 0
        ADCEQ       R0,R0,0     // R0 = R0 + C
        BX          LR          // **Returns 1 in R0**

//      Do flags that are changed by instruction in an IT block update which
//      subsequent instructions in the same IT block are enabled/disabled?

Test2:  MOV         R0,1        // R0 = 1
        CMP         R0,R0       // Z  = 1 (EQ)
        ITT         EQ
        CMPEQ       R0,0        // Z  = 0 (NE)
        MOVEQ       R0,0        // R0 = 0 ? (Disabled!)
        BX          LR          // **Returns 1 in R0**