2015-05-06 183 views
0

在Assembly中使用分支命令困惑,主要是BNEBEQ。 所以,我必须写的伪代码的汇编代码:如果其他OR语句在Assembly中?

X = 5,Y = 10,Z = 15

如果X = 4 & &ý== 10 || Z = 20

A = X + Y - 2

否则R 1 = Z - 5 + X

我编码凯尔uVision5的的ARM Cortex M0加(如果没有线索是需要信息)在它的低寄存器是R0-R7这个特定的板。

我知道如何编写if else声明本身,但我主要是问我如何处理代码的OR部分。明显的X!= 4是真的,并且Y == 10是真的,然后检查Z = 20是否为假,那么我将检查X!= 4是否先跳,使用BNE标签跳转来检查Y,使用BEQ来检查Z,这是错误的,但既然方程已经是真的,我会跳到BNE endif声明A=X+Y-2

然后在它们之间没有标签我会写汇编器的else语句,如果第一个BNE标签是某种错误..?

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

LDR R7, =X 
LDR R0, [R7] 
ADD R0, #5 ; X = 5 in R0 
CMP R0, #4 ; Compare X != 4 
BNE jumpToY 

jumpToY 
LDR R7, =Y 
LDR R1, [R7] ; Y = 10 in R1 
CMP R1, #10 ; Compare Y == 10 
BEQ jumpToZ 

jumpToZ 
etc... 
+0

测试失败后立即跳转到失败目标。 –

+0

对不起,我仍然是一个汇编程序的初学者,我将如何去分支到代码中的失败目标(这意味着else语句正确..?)。 @ IgnacioVazquez-Abrams –

+0

随着跳转指令。如果测试通过,你会跳过。 –

回答

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不是四个,那么我们分支为label0,做在那里,如果是四个,那么我们一直走下去,做如果Z == 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增加5至所以无论X是你加5

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 
0

想想你如何去评估你的脑中的逻辑条件。如果你想要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: 
    ... 
0
A EQU 0x2000000 
R EQU 0x2000004 
X EQU 0x2000008 
Y EQU 0x200000C 
Z EQU 0x2000010 

在这里,你可以看到条件指令,以防止多余的跳跃。我们检查And的第一个2个案例,然后默认为Or案例。注意,我们还必须跳过其他代码,以防止两者都执行。另外请注意,我们会遇到其他情况,以防止额外的跳转。

; 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更是如此。它应该展示如何处理你想要看到的和/或情况。

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