如果在汇编中还有OR语句?

时间:2015-05-06 20:06:55

标签: if-statement assembly arm cortex-m

在汇编中使用分支命令时感到困惑,主要是BNEBEQ。 所以我必须为伪代码编写汇编代码:

  

X = 5,Y = 10,Z = 15

     

如果X!= 4&& Y == 10 || Z = 20

     

A = X + Y - 2

     

否则R = Z - 5 + X

我在Keil uVision5中为ARM Cortex M0 Plus编写代码(如果需要这些信息,则无需提供信息)在其特定电路板的低R0-R7寄存器中。

我知道我如何编写if else语句本身,但我主要是询问我如何处理代码的OR部分。显然X!= 4是真的,Y == 10是真的,然后检查Z = 20是否为假,所以我先检查是否X!= 4,使用BNE标签跳转来检查是的,使用BEQ检查Z,这是假的,但由于方程式为真,我跳转到BNE的{​​{1}} endif语句?

然后介于两者之间没有标签我是否会为汇编程序编写else语句,如果第一个BNE标签在某种程度上是假的那么......?

A=X+Y-2

3 个答案:

答案 0 :(得分:1)

考虑如何评估头脑中的逻辑条件。如果你想要A或B然后你得到A那么你就不需要考虑B.如果你想要A和B并且你没有A,那么计算B就没有意义了。

有些纯粹主义者认为你应该评估这两个条件,然后对结果进行逻辑比较: 计算A. 计算B 和/或结果一起

幸运的是,工程方法赢了:

对于A和B(假设BEQ为"为真"):

Calculate A
BNE fail
Calculate B
BNE fail
success:
   ...
   RET/JMP somewhere  ; Don't drop through into fail
fail:
   ...

对于A或B(同样,假设BEQ为"为真"):

Calculate A
BEQ success
Calculate B
BNE fail
success:
   ...
   RET/JMP somewhere  ; Don't drop through into fail
fail:
   ...

答案 1 :(得分:1)

asm如何通常用于使用由一条指令设置的标志然后是条件指令的分支或跳转的处理器。在分支/跳转条件之前的某个时刻,您设置了标志,比较例如在这种情况下执行此操作。条件指令上的分支的工作方式是,如果条件为真,它将完全按照goto在C中的工作方式分支到该地址。如果条件不为真则不然。

if(x!=4) goto label0;
label2:
if(z==20) goto label1;
R = Z - 5 + X;
goto done;
label0:
if(y!=10) goto label2:
...
done:

所以如果x不是4那么从顶部开始我们分支到label0然后做那里的东西,如果它是4那么我们继续去做if if = = 20 然后重新关注z == 20,如果z == 20然后转到label1,那么继续进行数学运算。

在汇编中就像是

ldr r0,=X
ldr r0,[r0]
cmp r0,#4
bne label0

ldr r2,=Z
ldr r2,[r2]
cmp r2,#20
beq label1

sub r2,#5
add r0,r2
ldr r2,=X
str r0,[r2]
b done

label0:
ldr r1,=Y
ldr r1,[r1]
cmp r1,#10
bne label2:

...

done:

我在分支之后放置空格没有特别的原因。在第一个标签0上,如果确实发生了那么我们接下来执行标签0之后的内容,如果设置了相等的标志,则加载y地址然后我们不进行分支,我们继续执行Z地址的加载。

就覆盖逻辑路径而言,可能为每个X!= 4 Y == 10和Z == 20为自己制作一个真或假的真值表,结果是R =或A =,然后来自你最糟糕的情况是按字面意思执行真值表(8组比较)或缩小它...并保持优化直到你快乐。

最终你希望A =代码在某个地方有一个分支到函数的末尾,而R =代码在某个地方也有一个分支到函数的末尾,然后根据你的真值表和实现创建路径来获取到A =或R =代码,但你必须打一个或另一个。

编辑:

请注意您的前三行看起来不对

 LDR R7, =X
 LDR R0, [R7]
 ADD R0, #5  ; X = 5 in R0

这不是将X设置为5,因为你的评论意味着它将ADDS 5添加到X所以无论你添加了什么X都是。

如果你想实现这个X = 5,Y = 10,Z = 15

ldr r1,=X
mov r0,#5
str r0,[r1]
ldr r1,=Y
mov r0,#10
str r0,[r1]
ldr r1,=Z
mov r0,#15
str r0,[r1]

然后得到x并进行比较

LDR R7, =X
LDR R0, [R7]
CMP R0, #4  ; Compare X != 4

答案 2 :(得分:0)

A EQU 0x2000000
R EQU 0x2000004
X EQU 0x2000008
Y EQU 0x200000C
Z EQU 0x2000010

在这里,您可以看到防止额外跳跃的条件指令。我们检查前两个和第一个案例,然后默认为Or案例。另请注意,我们必须超越else代码以防止两者都执行。还要注意我们会落到其他情况,也是为了防止额外的跳跃。

 ; These could be loaded with a singl LDM instruction instead.
 LDR R7, =X
 LDR R0, [R7]
 LDR R7, =Y
 LDR R0, [R7]
 LDR R7, =Z
 LDR R2, [R7]

 CMP R0,#5
 CMPEQ R1,#10
 BEQ FirstCase

 CMP R2,#5
 BEQ FirstCase
 ;... Fall Through

ElseCase:
   ...
   j RestOfCode
FirstCase:
   ...

RestOfCode:

请注意我在盲人中编码,对任何语言都是危险的事情,ASM更是如此。它应该告诉你如何处理你想看到的And / Or案例。

您也可以将代码放入C编译器并检查输出,因为它也会显示工作代码。