使用谓词指令将c转换为汇编



我想使用谓词指令将此代码转换为汇编

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

它正确吗?或者我如何使用jump?

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

在后一种情况下,使用ARMv6预测作为研究案例(并继承关于寄存器使用的前提),程序集就是

;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。那么通常的方法是条件性分支2,如Nutan所示
这里有一个可读性稍高的版本:

 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实际偏移量将变为地址。

相关内容

  • 没有找到相关文章

最新更新