将c转换为带谓词指令的程序集
我想使用谓词指令将此代码转换为程序集将c转换为带谓词指令的程序集,c,assembly,arm,predicates,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
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 在后一种情况下,将其用作研究案例(并继承关于寄存器用法的前提),程序集只需
;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
表示较高时移动<代码>移动表示移动(如果较低或相同)。movgt
表示较大时移动<代码>移动表示如果小于或等于,则移动。它们意味着相同的算术比较,只是后者对有符号数字使用了正确的标志 我对指令进行了分组,因此很容易识别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
表示分支,一旦执行,下一条指令将从指定为操作数的标签(地址)中提取(例如从\u end\u(如果
)。bls
只是一个谓词的b
(bls
表示分支,如果较少或相同),通常称为条件分支
条件分支与普通分支一样,但如果指定的条件不满足,则可以“忽略”它们。如果满足条件,CPU执行跳转,从而从指定为操作数的标签获取下一条指令,则称为执行条件跳转。
如果不满足条件且CPU在分支后继续执行指令(程序流失败),则称为不执行 “条件”通常指设置和清除的标志。 一些指令,如
cmp
,设置并清除这些标志。其他指令,如
bls
使用这些标志
标志保存在专用寄存器中(ps
在ARM中),但也有一些架构,尤其是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个将成为地址的实际偏移量 你在问什么汇编语言?这是对一个不太好的问题的一个非常好的回答。干得好!在ARM上,
movr5,#0
是一种更好、更有效的寄存器归零方法。不使用异或(xor)感觉很奇怪,但这只适用于x86,在x86中,可变长度指令编码意味着避免立即字节实际上节省了空间,并被认为是一种归零习惯用法。在ARM Thumb2机器代码中,eor r5,r5
是4B指令,而mov r5,#0
是2B指令。另外,eor
将对旧值有错误的依赖性,因为没有理由将ARM微体系结构作为特例eor相同,相同的
作为归零习惯用法。@PeterCordes我的直觉告诉我没有归零习惯用法,但我懒得检查。谢谢提供,我正在更新答案。@PeterCordes:比这更糟:在ARM和POWER上,指令有意保持依赖性以保持内存顺序(这进入内存\u顺序\u消耗领域,这里是龙)。它在体系结构上不是一个破坏依赖关系的指令。在具有强内存模型的x86上,依赖项不需要通过数据处理指令进行跟踪。@EOF:ahh,我没有意识到数据依赖项的dep跟踪是针对弱有序体系结构(Alpha除外)进行记录的。我想MIPS也会记录它。谢谢你让我明白这一点;我只看过英特尔手册的细节,当然没有提到。如果Intel CPU在内部跟踪内存排序的数据依赖性,这样他们就可以以不影响全局可见排序的方式推测/OOO,我也不会感到惊讶。无论如何,有趣的是,ARM在体系结构上不需要进行xor归零中断依赖。