使用谓词指令将c转换为程序集

我想使用谓词指令将此代码转换为程序集

If (A>B){ C=A; D=B; E=0 } else{ C=B; } 

它是正确的还是我如何使用跳跃?

 cmp R1,R2; considering B is assigned to R2 and A assigned to R1 movlf R3,R1;R3 assign to C mov R4,R2;R4 assign to D mov R5,0; R5 assign to E movlt R3,R2 

警告 :回答新手。 可能会让有经验的用户死亡。


我不确定你是否滥用了这个术语,或者你是否真的想要使用谓词指令 1

在后一种情况下,使用ARM v6预测作为研究案例(并inheritance您关于寄存器使用的前提),程序集很简单

 ;r1 = A r2 = B r3 = C r4 = D r5 = E ; ;A, B unsigned | ;A, B signed | cmp r1, r2 | cmp r1, r2 | movhi r3, r1 | movgt r3, r1 movhi r4, r2 | movgt r4, r2 movhi r5, #0 | movgt r5, #0 | movls r3, r2 | movle r3, r2 

在这里,我根据涉及的变量的符号给出了两个版本。

movhi意味着移动,如果更高movls表示移动,如果更低或相同
movgt意味着移动更大movle表示移动,如果小于或等于
它们意味着相同的算术比较,只是后者使用适当的标志来签名数字。

我对指令进行了分组,因此很容易识别if-thenelse块。
请注意同一块中的指令如何具有相同的后缀(例如hils )。

真正使这个代码成为if-then-else结构而不是其他东西的事实是条件hilsgtle互斥的 (只有两个中的一个可以是真的)。
因此, 只能执行一个指令块

使用非互斥条件会产生多个if-then-else语句。


如果你滥用了这个术语而你实际上只想实现条件语句(或选择) ,即if-then-else ,那么通常的方法就是Nutan已经显示的条件分支 2
这里有一个稍微可读的版本:

  cmp r1, r2 bls _A_less_same_B mov r3, r1 mov r4, r2 eor r5, r5, r5 b _end_if _A_less_same_B: mov r3, r2 _end_if: 

由此决定转换此代码以使用有符号整数的负担。

以冒号(:)结尾的奇特单词称为标签 ,它们是在代码(和数据)中命名点的有用方法3
将其视为灵活的行号。

b表示分支 ,一旦执行,下一条指令就从指定为操作数的标签(地址)中取出(例如从_end_if )。
bls只是一个谓词bbls表示分支,如果更少或相同 ),通常称为条件分支

条件分支就像普通分支一样,但如果指定的条件无法满足,则可以“忽略”它们。
如果满足条件并且CPU执行跳转,则称为条件跳转,从而从指定为操作数的标签中取出下一指令。
如果不满足条件并且CPU从分支之后的指令继续执行(程序流程通过 ),则认为不采用。

“条件”通常表示设置和清除标志 。 一些指令,如cmp ,设置并清除这些标志。
其他指令,如bls使用这些标志。

标志保存在专用寄存器(ARM中的ps )中,但有一些架构,最明显的是MIPS,它们没有标志寄存器。

您可以用手指模拟程序流程。 例如,如果A > B ,流程如下:

  [Start Here] ¯¯¯¯+¯¯¯¯¯ cmp r1, r2 | bls _A_less_same_B + [Branch not taken, fall through] | mov r3, r1 | mov r4, r2 | eor r5, r5, r5 | | b _end_if +--[Branch always taken]----+ | _A_less_same_B: | mov r3, r2 | | _end_if: +--[Land here]--------------+ | V 

弯曲意味着画出“跳过”我们想要跳过的代码(在这种情况下为其他 )。


我不承认你的问题的集合味道,所以我无法帮助编写具体的例子。
我不会这样做,因为我觉得这个一般的解释是足够的,并希望我这样的努力不足会刺激你自己尝试解决这个问题。

这是学习路线上的必修课。


1获取,解码(可能也是已发出)的指令,但仅在设置或清除特定标志时执行。

2请注意,如果可能,最好避免使用条件分支 。 根据目标微架构,可以有更优化的方式来实现相同的结果。 这值得注意,现在不要理会它。

3实际上将成为地址的偏移量。