我想使用谓词指令将此代码转换为汇编
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-块
注意同一块中的指令如何具有相同的后缀(例如hi
和ls
)。
真正使此代码成为if-then-else构造而不是其他构造的是,条件hi
-ls
和gt
-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
只是一个谓词b
(bls
表示分支,如果小于或等于),通常称为条件分支。
条件分支与普通分支一样,但如果指定的条件不满足,则可以"忽略"它们
如果条件满足并且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实际偏移量将变为地址。