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

时间:2016-05-14 05:34:10

标签: c assembly arm predicates

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

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 个答案:

答案 0 :(得分:7)

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

我不确定您是否滥用了这个术语,或者您是否真的想使用predicated instructions 1

在后一种情况下,使用ARM v6 predication作为研究案例(并继承有关注册用法的前提),程序集就是

;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-then else 块。
请注意同一块中的指令具有相同的后缀(例如hils)。

真正使这段代码成为 if-then-else 构造而不是其他东西的是条件hi - lsgt - le 互斥(两个中只有一个可以为真) 所以只能执行一个指令块

使用非互斥条件会产生多个 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表示 branch ,一旦执行,下一条指令就从指定为操作数的标签(地址)中获取(例如来自_end_if)。
bls只是一个谓词bbls表示分支,如果更少或相同),通常称为条件分支

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

“条件”通常表示标志设置和清除。 某些指令(如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

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

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

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

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

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

3 实际上会成为地址的抵消。