大多数示例都具有以下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块的另一种方法?这些示例中到底发生了什么?
答案 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
的极端情况,而不是使用它实际执行特定操作的完整/完整示例。
条件分支指令的文档通常也不会显示标志设置指令。
除了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**