首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果还有其他或在程序集中的声明?

如果还有其他或在程序集中的声明?
EN

Stack Overflow用户
提问于 2015-05-06 20:06:54
回答 3查看 9.8K关注 0票数 0

在程序集中使用分支命令(主要是BNEBEQ )时感到困惑。因此,我必须为伪代码编写一个汇编代码:

代码语言:javascript
复制
X = 5, Y = 10, Z = 15

if X != 4 && Y == 10 || Z = 20 

A = X + Y - 2

else   R = Z - 5 + X

我正在编码在Keil uVision5的ARM皮质M0加法(如果这是需要的信息)在它的低寄存器,这是R0-R7为这个特定的板。

我知道如何编写if else语句本身,但我主要问的是如何处理代码的OR部分。显而易见的X!=4为真,Y==10为真,然后检查Z = 20是否为false,所以我将首先检查X!=4是否为假,使用BNE标签跳转以检查Y,使用BEQ检查Z,这是假的,但由于等式已经为真,所以我会跳到A=X+Y-2BNE endif语句

然后在中间没有标签在它前面,我会写其他的语句,让汇编程序去,如果第一个BNE标签是错误的..?

代码语言:javascript
复制
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...
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-06 20:56:57

asm一般用于使用由一条指令设置的标志的处理器,然后是分支或跳转条件指令。在设置标志的条件下,在分支/跳转之前的某个点,例如,在本例中,比较会执行此操作。条件指令上的分支的工作方式是,如果条件为true,则分支到该地址的方式与goto在C中的工作方式完全相同。如果条件不为真,则不为真。

代码语言:javascript
复制
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,那么我们继续做如果z==20,然后重新聚焦在z==20上,如果z==20,然后去label1,继续做数学。

在汇编中,这将类似于

代码语言:javascript
复制
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:

我在树枝后面放了空位,没有什么特别的理由。在第一个bne label0上,如果发生这种情况,那么我们接下来执行标签0之后的内容,如果设置了相等的标志,则加载y地址,然后不分支,我们继续执行Z地址的加载。

就覆盖逻辑路径而言,对于X!=4 Y==10和Z==20中的每一个,可能为自己创建一个真值表,结果要么是R=,要么是A=,然后您可以在最坏的情况下逐字执行真值表(8组比较)或缩小真值表,down...and一直优化到您满意为止。

最终,您希望A=代码具有到函数末尾的分支,而R=代码也希望分支到函数的末尾,然后根据您的真值表和实现创建到A=或R=代码的路径,但您必须点击其中的一个。

编辑:

注意你的前三行看上去不对

代码语言:javascript
复制
 LDR R7, =X
 LDR R0, [R7]
 ADD R0, #5  ; X = 5 in R0

这并不是将X设置为5,正如您的注释所暗示的那样,它将5添加到X,所以不管您添加了什么X。

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

代码语言:javascript
复制
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并比较它

代码语言:javascript
复制
LDR R7, =X
LDR R0, [R7]
CMP R0, #4  ; Compare X != 4
票数 1
EN

Stack Overflow用户

发布于 2015-05-06 20:41:05

想想你是如何在头脑中评估逻辑条件的。如果你想要A或者B,你就不需要考虑B,如果你想要A和B,你没有A,那么计算B就没有意义了。

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

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

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

代码语言:javascript
复制
Calculate A
BNE fail
Calculate B
BNE fail
success:
   ...
   RET/JMP somewhere  ; Don't drop through into fail
fail:
   ...

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

代码语言:javascript
复制
Calculate A
BEQ success
Calculate B
BNE fail
success:
   ...
   RET/JMP somewhere  ; Don't drop through into fail
fail:
   ...
票数 2
EN

Stack Overflow用户

发布于 2015-05-06 20:43:22

代码语言:javascript
复制
A EQU 0x2000000
R EQU 0x2000004
X EQU 0x2000008
Y EQU 0x200000C
Z EQU 0x2000010

在这里,您可以看到有条件的指令,以防止额外的跳跃。我们首先检查前2种情况,然后默认为或情况。注意,我们还必须跳过其他代码,以防止这两个代码的执行。还注意到我们掉到了其他情况下,也是为了防止额外的跳跃。

代码语言:javascript
复制
 ; 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编译器并检查输出,因为它也将显示工作代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30086526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档